You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/10-error-handling/2-custom-errors/article.md
+36-35Lines changed: 36 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,9 +123,9 @@ try {
123
123
124
124
همچنین مهم است که اگر `catch` یک ارور ناشناس را ملاقات کند، در خط `(**)` آن را rethrow کند. بلوک `catch` فقط میداند که چگونه ارورهای سینتکس و اعتبارسنجی را مدیریت کند، انواع دیگر (که به خاطر یک غلط املایی در کد یا هر دلیل دیگری ایجاد شدهاند) باید از آن بیرون بیافتند.
125
125
126
-
## Further inheritance
126
+
## ارثبری بیشتر
127
127
128
-
The`ValidationError`class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for`age`instead of a number). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
128
+
کلاس`ValidationError`خیلی عام است. ممکن است چیزهای زیادی به درستی انجام نگیرند. ویژگی ممکن است وجود نداشته باشد یا شکل اشتباهی داشته باشد (مانند یک مقدار رشتهای برای`age`به جای یک عدد). بیایید دقیقا برای نبودن ویژگیها، یک کلاس عینیتر `PropertyRequiredError` بسازیم. این کلاس شامل اطلاعات بیشتری درباره ویژگیای که وجود ندارد است.
129
129
130
130
```js run
131
131
classValidationErrorextendsError {
@@ -145,7 +145,7 @@ class PropertyRequiredError extends ValidationError {
145
145
}
146
146
*/!*
147
147
148
-
//Usage
148
+
//کاربرد
149
149
functionreadUser(json) {
150
150
let user =JSON.parse(json);
151
151
@@ -159,7 +159,7 @@ function readUser(json) {
159
159
return user;
160
160
}
161
161
162
-
//Working example with try..catch
162
+
// try..catch مثال عملی با
163
163
164
164
try {
165
165
let user =readUser('{ "age": 25 }');
@@ -173,18 +173,18 @@ try {
173
173
} elseif (err instanceofSyntaxError) {
174
174
alert("JSON Syntax Error: "+err.message);
175
175
} else {
176
-
throw err; //unknown error, rethrow it
176
+
throw err; //کن rethrow ارور ناشناخته، آن را
177
177
}
178
178
}
179
179
```
180
180
181
-
The new class `PropertyRequiredError`is easy to use: we only need to pass the property name: `newPropertyRequiredError(property)`. The human-readable `message`is generated by the constructor.
181
+
استفاده از کلاس جدید `PropertyRequiredError`آسان است: ما فقط باید اسم ویژگی را پاس دهیم: `newPropertyRequiredError(property)`. پیام `message`که برای انسان خوانا است توسط تابع سازنده تولید میشود.
182
182
183
-
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign`this.name=<classname>`in every custom error class. We can avoid it by making our own "basic error" class that assigns `this.name=this.constructor.name`. And then inherit all our custom errors from it.
183
+
لطفا توجه کنید که در تابع سازنده `PropertyRequiredError` مقدار `this.name` دوباره به صورت دستی مشخص میشود. این موضوع ممکن است کمی خستهکننده باشد -- مشخص کردن`this.name=<classname>`در هر کلاس شخصیسازی شده ارور. ما میتوانیم با ایجاد کلاس «ارور پایه» خودمان که `this.name=this.constructor.name` را مشخص میکند از آن دوری کنیم. و سپس تمام ارورهای شخصیسازی شده خودمان را از آن ارثبری کنیم.
184
184
185
-
Let's call it`MyError`.
185
+
بیایید به آن`MyError` بگوییم.
186
186
187
-
Here's the code with `MyError`and other custom error classes, simplified:
187
+
اینجا کد `MyError`و دیگر کلاسهای ارور شخصیسازی شده را داریم، ساده شده:
188
188
189
189
```js run
190
190
classMyErrorextendsError {
@@ -205,51 +205,51 @@ class PropertyRequiredError extends ValidationError {
Now custom errors are much shorter, especially `ValidationError`, as we got rid of the `"this.name = ..."`line in the constructor.
212
+
حالا ارورهای شخصیسازی شده بسیار کوتاهتر هستند مخصوصا `ValidationError`، چون ما از خط `"this.name = ..."`در تابع سازنده خلاصی یافتیم.
213
213
214
-
## Wrapping exceptions
214
+
## دربرگرفتن استثناءها
215
215
216
-
The purpose of the function `readUser`in the code above is "to read the user data". There may occur different kinds of errors in the process. Right now we have `SyntaxError`and`ValidationError`, but in the future `readUser`function may grow and probably generate other kinds of errors.
216
+
هدف تابع `readUser`در کد بالا «خواندن داده کاربر» است. ممکن است در حین این فرایند انواع مختلفی از ارور رخ دهد. هم اکنون ما `SyntaxError`و`ValidationError` را داریم اما در آینده تابع `readUser`ممکن است رشد کند و احتمالا انواع دیگری از ارورها را ایجاد کند.
217
217
218
-
The code which calls `readUser`should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones.
218
+
کدی که `readUser`را فرا میخواند باید این ارورها را مدیریت کند. هم اکنون، این کد در بلوک `catch` از چند `if` استفاده میکند که کلاس را بررسی و ارورهای شناخته شده را مدیریت میکند و ارورهای ناشناخته را rethrow میکند.
219
219
220
-
The scheme is like this:
220
+
رویه اینگونه است:
221
221
222
222
```js
223
223
try {
224
224
...
225
-
readUser() //the potential error source
225
+
readUser() //منبع احتمالی ارور
226
226
...
227
227
} catch (err) {
228
228
if (err instanceof ValidationError) {
229
-
//handle validation errors
229
+
//مدیریت ارورهای اعتبارسنجی
230
230
} elseif (err instanceofSyntaxError) {
231
-
//handle syntax errors
231
+
//مدیریت ارورهای سینتکس
232
232
} else {
233
-
throw err; //unknown error, rethrow it
233
+
throw err; //میکنیم rethrow ارور ناشناخته، آن را
234
234
}
235
235
}
236
236
```
237
237
238
-
In the code above we can see two types of errors, but there can be more.
238
+
در کد بالا میتوانیم دو نوع از ارور را ببینیم اما بیشتر از آن هم میتواند وجود داشته باشد.
239
239
240
-
If the`readUser`function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one every time?
240
+
اگر تابع`readUser`چند نوع ارور تولید کند، سپس ما باید از خودمان بپرسیم: آیا واقعا میخواهیم هر بار برای تک تک ارورها بررسی انجام دهیم؟
241
241
242
-
Often the answer is "No": we'd like to be "one level above all that". We just want to know if there was a "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, we'd like to have a way to get the error details, but only if we need to.
242
+
اغلب اوقات جواب «خیر» است: ما میخواهیم «یک پله بالاتر از تمام آنها» باشیم. ما فقط میخواهیم بدانیم آیا یک «ارور خواندن داده» وجود داشت یا خیر -- اینکه دقیقا چرا اتفاق افتاد اغلب اوقات نامربوط است (پیام ارور این موضوع را توضیح میدهد). یا، حتی بهتر، میخواهیم راهی برای دریافت جزئیات ارور داشته باشیم اما فقط در صورتی که نیاز ما باشد.
243
243
244
-
The technique that we describe here is called "wrapping exceptions".
244
+
تکنیکی که ما اینجا شرح میدهیم «دربرگرفتن استثناءها (wrapping exceptions)» نام برده میشود.
245
245
246
-
1. We'll make a new class`ReadError`to represent a generic "data reading" error.
247
-
2. The function `readUser`will catch data reading errors that occur inside it, such as`ValidationError`and`SyntaxError`, and generate a `ReadError`instead.
248
-
3. The`ReadError`object will keep the reference to the original error in its `cause`property.
246
+
1. ما کلاس جدیدی به نام`ReadError`برای نمایش یک ارور «خواندن داده» عام میسازیم.
247
+
2. تابع `readUser`ارورهای خواندن داده که درون آن اتفاق میافتند را میگیرد، مانند`ValidationError`و`SyntaxError`، و به جای آنها یک `ReadError`تولید میکند.
248
+
3. شیء`ReadError`رجوع به ارور اصلی را درون ویژگی `cause`خودش حفظ خواهد کرد.
249
249
250
-
Then the code that calls `readUser` will only have to check for `ReadError`, not for every kind of data reading errors. And if it needs more details of an error, it can check its`cause`property.
250
+
سپس کدی که `ReadUser` را فرا میخواند فقط باید برای وجود داشتن `ReadError` بررسی را انجام دهد نه برای هر نوع ارور خواندن داده. و اگر کد به اطلاعات بیشتری درباره یک ارور نیاز داشت، میتواند ویژگی`cause`آن را بررسی کند.
251
251
252
-
Here's the code that defines `ReadError`and demonstrates its use in `readUser`and`try..catch`:
252
+
اینجا کدی داریم که `ReadError`را تعریف میکند و کاربرد آن در `readUser`و`try..catch` را نشان میدهد:
253
253
254
254
```js run
255
255
classReadErrorextendsError {
@@ -308,7 +308,7 @@ try {
308
308
if (e instanceof ReadError) {
309
309
*!*
310
310
alert(e);
311
-
//Original error: SyntaxError: Unexpected token b in JSON at position 1
311
+
// SyntaxError: Unexpected token b in JSON at position 1 :ارور اصلی
312
312
alert("Original error: "+e.cause);
313
313
*/!*
314
314
} else {
@@ -317,14 +317,15 @@ try {
317
317
}
318
318
```
319
319
320
-
In the code above, `readUser`works exactly as described -- catches syntax and validation errors and throws `ReadError`errors instead (unknown errors are rethrown as usual).
320
+
در کد بالا، `readUser`دقیقا همانطور که توضیح داده شد کار میکند -- ارورهای سینتکس و اعتبارسنجی را میگیرد و به جای آنها، ارورهای `ReadError`را پرتاب میکند (ارورهای ناشناخته طبق معمول دوباره پرتاب میشوند).
321
321
322
-
So the outer code checks `instanceof ReadError`and that's it. No need to list all possible error types.
322
+
پس کد بیرونی `instanceof ReadError`را بررسی میکند و تمام. نیازی به لیست کردن تمام انواع ارور احتمالی نیست.
323
323
324
324
The approach is called "wrapping exceptions", because we take "low level" exceptions and "wrap" them into `ReadError` that is more abstract. It is widely used in object-oriented programming.
325
+
این روش «دربرگرفتن استثناءها» نامیده میشود چون ما استثناءهای «سطح پایین» را دریافت میکنیم و آنها را درون `ReadError` که خلاصهتر است «دربرمیگیریم».
325
326
326
-
## Summary
327
+
## خلاصه
327
328
328
-
- We can inherit from `Error`and other built-in error classes normally. We just need to take care of the `name`property and don't forget to call `super`.
329
-
- We can use `instanceof`to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from a 3rd-party library and there's no easy way to get its class. Then `name`property can be used for such checks.
330
-
- Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like `err.cause`in the examples above, but that's not strictly required.
329
+
- به طور طبیعی ما میتوانیم از `Error`و سایر کلاسهای ارور درونساخت ارثبری کنیم. فقط باید حواسمان به ویژگی `name`باشد و فراخوانی `super` را فراموش نکنیم.
330
+
- میتوانیم از `instanceof`برای بررسی وجود داشتن ارورهای به خصوص استفاده کنیم. این همراه با ارثبری نیز کار میکند. اما گاهی اوقات ما یک شیء ارور داریم که از یک کتابخانه شخص ثالث میآید و راه آسانی برای دریافت کلاس آن وجود ندارد. سپس ویژگی `name`میتواند برای چنین بررسیهایی استفاده شود.
331
+
- دربرگرفتن استثناءها یک تکنیک همه جانبه است: یک تابع استثناءهای سطح پایین را مدیریت میکند و به جای تعداد زیادی ارور سطح پایین، ارورهای سطح بالاتر میسازد. گاهی اوقات استثناءهای سطح پایین به ویژگیهای آن شیء تبدیل میشوند مانند `err.cause`در مثالهای بالا اما این موضوع ضروری نیست.
0 commit comments