1-js/08-error-handling/2-custom-errors#115
1-js/08-error-handling/2-custom-errors#115leviding merged 18 commits intojavascript-tutorial:zh-hansfrom lihanxiang:translation/js-08
Conversation
继承 SyntaxError
继承 SyntaxError
继承 SyntaxError
|
校对认领 |
|
@sakila1012 ok |
| 创造一个继承自内置类 `SyntaxError` 的 `FormatError` 类。 | ||
|
|
||
| It should support `message`, `name` and `stack` properties. | ||
| 它应该支持 `message`、 `name` 和 `stack` 属性。 |
| 当我们在进行开发的时候,通常需要属于我们自己的错误类来反映任务中可能出现的特殊情况。对于网络操作错误,我们需要 `HttpError`,对于数据库操作错误,我们需要 `DbError`,对于搜索操作错误,我们需要 `NotFoundError`,等等。 | ||
|
|
||
| Our errors should support basic error properties like `message`, `name` and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError` objects may have `statusCode` property with a value like `404` or `403` or `500`. | ||
| 我们自定义的错误应该具有基本的错误属性,例如 `message`、`name` 以及更加详细的 `stack`。但是它们也会有属于自己的属性。举个例子,`HttpError`对象会有一个 `statusCode` 属性,取值可能为 `404`、`403` 或 `500` 等。 |
There was a problem hiding this comment.
我们自定义的错误应该具有基本的错误属性,例如 message,name 以及更加详细的 stack。但是它们也会有属于自己的属性。举个例子,HttpError 对象会有一个 statusCode 属性,取值可能为 404、403 或 500 等。
| @@ -1,33 +1,33 @@ | |||
| # Custom errors, extending Error | |||
| # 自定义以及拓展错误 | |||
| 但即使是格式正确的 `json`,也并不表示它就是可用的,对吧?它有可能会遗漏一些必要的数据。例如,缺失了对用户有必要的 `name` 和 `age` 属性。 | ||
|
|
||
| Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field. | ||
| 函数 `readUser(json)` 不止会读取 JSON,也会检查(验证)数据的。如果没有所需要的属性,或者格式不正确,就会发生错误。而这不是 `SyntaxError`,因为数据在语法上时正确的,但是有其他的错误。我们称之为 `ValidationError` 并且为之创建一个类。这种类型的错误也应该承载缺少的字段的信息。 |
There was a problem hiding this comment.
函数 readUser(json) 不仅会读取 JSON,也会检查(验证)数据。
| 使用 `instanceof` 的做法会好很多,因为我们在以后会扩展 `ValidationError`,创造一个它的子类型,例如 `PropertyRequiredError`。而 `instanceof` 对于新的继承类也适用。所以这是个长远的保证。 | ||
|
|
||
| Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or such) should fall through. | ||
| 还有一点很重要,在 `catch` 语句捕捉到未知的错误时,它会抛出在行 `(**)` 处重新抛出,`catch` 语句仅仅知道如何处理验证和语法错误,而其他错误不应该被捕获。 |
There was a problem hiding this comment.
还有一点很重要,在 catch 语句捕捉到未知的错误时,它会在抛出行 (**) 处重新抛出,catch 语句仅仅知道如何处理验证和语法错误,而其他错误不应该被捕获。
| 这个 `PropertyRequiredError` 十分容易上手:我们只需要传递属性名:`new PropertyRequiredError(property)`。易懂的 `message` 属性将会由构造器提供。 | ||
|
|
||
| Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedius -- to assign `this.name = <class name>` when creating each custom error. But there's a way out. We can make our own "basic error" class that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in the constructor. And then inherit from it. | ||
| 需要注意的是,在 `PropertyRequiredError` 构造器中的 `this.name` 是再次进行手动赋值的。这可能会造成冗余 —— 在创建每个自定义错误的时候都要进行赋值 `this.name = <class name>`。但这并不是唯一的办法。我们可以创建自己的“基础异常”类,通过将 `this.constructor.name` 赋值给 `this.name`,然后再进行继承。 |
There was a problem hiding this comment.
But there's a way out. We can make our own "basic error" class that removes this burden from our shoulders by using this.constructor.name for this.name in the constructor.这一句没有翻译完,遗漏部分
| ``` | ||
|
|
||
| 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). | ||
| 上述代码中, `readUser` 正如描述的一样正常工作 —— 捕获语法以及验证的异常并且使用抛出 `ReadError`用来代替之前的行为(未知的异常依旧重新抛出)。 |
There was a problem hiding this comment.
上述代码中, readUser 正如描述的一样正常工作 —— 捕获语法以及验证的异常并且使用抛出 ReadError 异常用来代替之前的行为(未知的异常依旧重新抛出)。
| 所以外部代码负责检测 `instanceof ReadError`,不必列出所有可能的异常类型。 | ||
|
|
||
| The approach is called "wrapping exceptions", because we take "low level exceptions" and "wrap" them into `ReadError` that is more abstract and more convenient to use for the calling code. It is widely used in object-oriented programming. | ||
| 这种途径称为“包装异常”,因为我们将“低级别的异常”包装为 `ReadError` ,这会使得调用代码更加的方便。它在面向对象编程中广泛使用。 |
There was a problem hiding this comment.
这种途径称为“包装异常”,因为我们将“低级别的异常”包装为 ReadError ,这会使得调用代码更加的抽象和方便。它在面向对象编程中广泛使用。
|
@leviding 校对认领 |
MeFelixWang
left a comment
There was a problem hiding this comment.
我是第一次参与校对,提出的review多数是针对的注释没有翻译,有不对的地方还请包涵
| 在这里面,我们使用 `JSON.parse`。如果它接收到错误的 `json`,就会抛出 `SyntaxError`。 | ||
|
|
||
| But even if `json` is syntactically correct, that doesn't mean that it's a valid user, right? It may miss the necessary data. For instance, if may not have `name` and `age` properties that are essential for our users. | ||
| 但即使是格式正确的 `json`,也并不表示它就是可用的,对吧?它有可能会遗漏一些必要的数据。例如,缺失了对用户有必要的 `name` 和 `age` 属性。 |
There was a problem hiding this comment.
『例如,缺失了对用户有必要的 name 和 age 属性』=>『例如,缺失了对于用户所必需的 name 和 age 属性』
| 但即使是格式正确的 `json`,也并不表示它就是可用的,对吧?它有可能会遗漏一些必要的数据。例如,缺失了对用户有必要的 `name` 和 `age` 属性。 | ||
|
|
||
| Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field. | ||
| 函数 `readUser(json)` 不仅会读取 JSON,也会检查(验证)数据。如果没有所需要的属性,或者格式不正确,就会发生错误。而这不是 `SyntaxError`,因为数据在语法上时正确的,但是有其他的错误。我们称之为 `ValidationError` 并且为之创建一个类。这种类型的错误也应该承载缺少的字段的信息。 |
There was a problem hiding this comment.
『如果没有所需要的属性,或者格式不正确,就会发生错误。』=>『如果没有所需要的字段,或者格式不正确,那也是错误。』
| 但即使是格式正确的 `json`,也并不表示它就是可用的,对吧?它有可能会遗漏一些必要的数据。例如,缺失了对用户有必要的 `name` 和 `age` 属性。 | ||
|
|
||
| Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field. | ||
| 函数 `readUser(json)` 不仅会读取 JSON,也会检查(验证)数据。如果没有所需要的属性,或者格式不正确,就会发生错误。而这不是 `SyntaxError`,因为数据在语法上时正确的,但是有其他的错误。我们称之为 `ValidationError` 并且为之创建一个类。这种类型的错误也应该承载缺少的字段的信息。 |
| 代码如下: | ||
|
|
||
| ```js | ||
| // The "pseudocode" for the built-in Error class defined by JavaScript itself |
There was a problem hiding this comment.
注释也要翻译:『The "pseudocode" for the built-in Error class defined by JavaScript itself』=>『由JavaScript本身定义的内置错误类“伪代码”』
| @@ -40,7 +40,7 @@ class Error { | |||
| } | |||
There was a problem hiding this comment.
注释也要翻译:『(different names for different built-in error classes)』=>『(不同内置错误类别的名称)』
| - We can inherit from `Error` and other built-in error classes normally, just need to take care of `name` property and don't forget to call `super`. | ||
| - Most of the time, we should use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name` property can be used for such checks. | ||
| - Wrapping exceptions is a widespread technique when a function handles low-level exceptions and makes a higher-level object to report about the errors. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required. | ||
| - 我们能够继承 `Error` 以及其他内置的类,只需要注意 `name` 属性以及调用 `super`。 |
There was a problem hiding this comment.
『我们能够继承 Error 以及其他内置的类,只需要注意 name 属性以及调用 super。』=>『我们能够正常地继承 Error 以及其他内置的错误类,只需要注意 name 属性以及不要忘了调用 super。』
| - Wrapping exceptions is a widespread technique when a function handles low-level exceptions and makes a higher-level object to report about the errors. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required. | ||
| - 我们能够继承 `Error` 以及其他内置的类,只需要注意 `name` 属性以及调用 `super`。 | ||
| - 大多数时候,我们应该使用 `instanceof` 来检测一些特定的异常。它也能够在继承中使用。但有时我们会发现来自第三方库的异常,并且不容易得到它的类。那么 `name` 属性就可用于这一类的检测。 | ||
| - 包装异常是一种广泛应用的技术,当一个函数处理低级别的异常时,用一个高级别的对象来报告错误。低级别的异常有时会变成这个对象的属性,就像上面例子中的 `err.cause`,但这不是严格的要求。 |
There was a problem hiding this comment.
『包装例外是一种广泛应用的技术,当一个函数处理低级别的异常时,用一个高级别的对象来报告异常。低级别的异常有时会变成这个对象的属性,就像上面例子中的 err.cause,但这并不严格要求。』
| 现在的自定义错误更加的简洁,特别是 `ValidationError`,我们在其构造器中删除了 `"this.name = ..."` 这一行。 | ||
|
|
||
| ## Wrapping exceptions | ||
| ## 包装异常 |
There was a problem hiding this comment.
感觉翻译为 异常 会更合适一些吧
| 在我们进行开发时,我们自己的异常类通常是有层次结构的,例如 `HttpTimeoutError` 可能继承自 `HttpError` 等。 | ||
|
|
||
| ## Extending Error | ||
| ## 可扩展错误 |
| @@ -1,33 +1,33 @@ | |||
| # Custom errors, extending Error | |||
| # 自定义以及继承错误 | |||
|
@leviding @lihanxiang 校对完成 |
|
@lihanxiang 再修改下吧 |
| 创造一个继承自内置类 `SyntaxError` 的 `FormatError` 类。 | ||
|
|
||
| It should support `message`, `name` and `stack` properties. | ||
| 它应该支持 `message`, `name` 和 `stack` 属性。 |
| alert( err instanceof SyntaxError ); // true (because inherits from SyntaxError) | ||
| ``` | ||
| alert( err instanceof SyntaxError ); // true (因为它继承自 SyntaxError) | ||
| ``` |
| alert( err instanceof FormatError ); // true | ||
| alert( err instanceof SyntaxError ); // true (because inherits from SyntaxError) | ||
| ``` | ||
| alert( err instanceof SyntaxError ); // true (因为它继承自 SyntaxError) |
There was a problem hiding this comment.
true (因为它继承自 SyntaxError) => true(因为它继承自 SyntaxError)
翻译的内容这里括号用全角,且前后不加空格
| 当我们在进行开发的时候,通常需要属于我们自己的错误类来反映任务中可能出现的特殊情况。对于网络操作错误,我们需要 `HttpError`,对于数据库操作错误,我们需要 `DbError`,对于搜索操作错误,我们需要 `NotFoundError`,等等。 | ||
|
|
||
| Our errors should support basic error properties like `message`, `name` and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError` objects may have `statusCode` property with a value like `404` or `403` or `500`. | ||
| 我们自定义的错误应该具有基本的错误属性,例如 `message`,`name` 以及更加详细的 `stack`。但是它们也会有属于自己的属性。举个例子,`HttpError`对象会有一个 `statusCode` 属性,取值可能为 `404`、`403` 或 `500` 等。 |
| 我们的 `ValidationError` 类应该继承自内置的 `Error` 类。 | ||
|
|
||
| That class is built-in, but we should have its approximate code before our eyes, to understand what we're extending. | ||
| `Error` 类是内置的,但是我们需要看一下大致的代码,来理解我们需要扩展什么。 |
| ## 更进一步的继承 | ||
|
|
||
| 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`). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing. | ||
| `ValidationError` 类是十分通用的。因此可能会在某些方面出错。属性可能缺失,格式可能发生错误(例如 `age` 属性的值为一个字符串)。让我们来创造一个更加具体的类 `PropertyRequiredError`,为属性缺失的错误而量身定做的。它将会承载属性缺失的相关信息。 |
| } | ||
|
|
||
| // Working example with try..catch | ||
| // try..catch实例 |
|
|
||
| // name is correct | ||
| alert( new PropertyRequiredError("field").name ); // PropertyRequiredError | ||
| alert( new PropertyRequiredError("field").name ); // 必有属性错误 |
There was a problem hiding this comment.
这句的注释就不翻译了,因为这是函数名吧。文中其他位置是否有类似的情况?注意一下。
| *!* | ||
| alert(e); | ||
| // Original error: SyntaxError: Unexpected token b in JSON at position 1 | ||
| // 原错误:语法错误:在位置1处不应有 b |
| ``` | ||
|
|
||
| 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). | ||
| 上述代码中, `readUser` 正如描述的一样正常工作 —— 捕获语法以及验证的异常并且抛出 `ReadError` 异常用来代替之前的行为(未知的异常依旧重新抛出)。 |



resolve #108