Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

错误处理 #98

Open
Genluo opened this issue Aug 31, 2020 · 0 comments
Open

错误处理 #98

Genluo opened this issue Aug 31, 2020 · 0 comments

Comments

@Genluo
Copy link
Owner

Genluo commented Aug 31, 2020

JavaScript Errors and generic handling

throw new Error('something went wrong')将在JavaScript中创建Error的实例,并停止脚本的执行,除非您对Error进行了拦截处理。当您开始以JavaScript开发人员的职业生涯时,您很可能不会自己这样做,而是从其他库(或运行时)中看到了它,例如,“ ReferenceError:fs is undefined”或类似内容。浏览器中Error类型的定义如下:

interface Error {
    name: string;
    message: string;
    stack?: string;
}

interface ErrorConstructor {
    new(message?: string): Error;
    (message?: string): Error;
    readonly prototype: Error;
}

declare var Error: ErrorConstructor;

1. The Error Object

Error对象具有两个内置属性供我们使用。

第一个是message,它是您作为参数传递给Error构造函数的信息,例如new Error('This is the message')。您可以通过message属性访问消息:

const myError = new Error(“请改善您的代码”)
console.log(myError.message)//请改善您的代码

第二个,非常重要的一个是错误堆栈跟踪。您可以通过stack属性访问它。错误堆栈将为您提供导致错误的“负责”文件的历史记录(调用堆栈)。堆栈还在顶部包括消息,然后是实际堆栈,该堆栈从错误的最新/隔离点开始,一直到最向外的“调用”文件:

Error: please improve your code at Object.<anonymous> (/Users/gisderdube/Documents/_projects/hacking.nosync/error-handling/src/general.js:1:79)
     at Module._compile (internal/modules/cjs/loader.js:689:30)
     at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
     at Module.load (internal/modules/cjs/loader.js:599:32)
     at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
     at Function.Module._load (internal/modules/cjs/loader.js:530:3)
     at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
     at startup (internal/bootstrap/node.js:266:19)
     at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)

2. The Error Types

javascript中内置了7种错误类型:

  • EvalError

    创建一个error实例,表示错误的原因:与 eval() 有关。

  • InternalError

    创建一个代表Javascript引擎内部错误的异常抛出的实例。 如: "递归太多".

  • RangeError

    创建一个error实例,表示错误的原因:数值变量或参数超出其有效范围。

  • ReferenceError

    创建一个error实例,表示错误的原因:无效引用。

  • SyntaxError

    创建一个error实例,表示错误的原因:eval()在解析代码的过程中发生的语法错误。

  • TypeError

    创建一个error实例,表示错误的原因:变量或参数不属于有效类型。

  • URIError

    创建一个error实例,表示错误的原因:给 encodeURI()decodeURl()传递的参数无效。

3. Throwing and Handling Errors

如果仅生成Error实例不会导致任何事情。例如new Error('...'),不执行任何操作。当Error变为throw时,它会变得更加有趣。然后,如前所述,除非您在处理过程中以某种方式拦截处理错误,否则脚本将停止执行。

Generating and handling Errors

关于如何处理错误,有不同的方法。我将向您展示使用自定义Error构造函数和Error Codes的方法,我们可以轻松地将其传递给您的前端或任何API使用者,一般存在两种错误类型

  1. 通用错误处理(某种后备),基本上只是说:“出了点问题,请重试或与我们联系”。这不是特别聪明,但是至少会通知用户出了点问题–而不是无限加载或类似的错误。
  2. 特定的错误处理,以便为用户提供有关错误的详细信息以及如何解决错误的详细信息,例如,缺少某些信息,该条目已经存在于数据库中,等等。

1. Building a custom Error constructor

我们将使用现有的Error构造函数并将其扩展。用JavaScript进行继承是一件冒险的事情,但是在这种情况下,我觉得它非常有用。我们为什么需要它?我们仍然希望堆栈跟踪为我们提供良好的调试体验。扩展JavaScript Error 可免费提供堆栈跟踪。

class CustomError extends Error {
    constructor(code = 'GENERIC', status = 500, ...params) {
        super(...params)

        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, CustomError)
        }

        this.code = code
        this.status = status
    }
}

module.exports = CustomError

2. How to use the customer Error

准备使用我们的自定义错误后,我们需要设置路由结构。正如我所指出的,我们希望对错误进行处理的唯一事实,这意味着对于每条路线,我们都希望具有相同的错误处理行为。默认情况下,express并不真正支持,因为路由都是封装的。

为了解决该问题,我们可以实现路由处理程序并将实际的路由逻辑定义为普通函数。这样,万一路由函数(或其中的任何函数)抛出错误,它将被返回到路由处理程序,然后路由处理程序可以将其传递给前端。每当后端发生错误时,我们都希望以以下格式将响应传递给前端(假设使用JSON API):

{
    error: 'SOME_ERROR_CODE',
    description: 'Something bad happened. Please try again or     contact support.'
}

那么其中的路由处理程序可以这种使用这个错误

try {
  const result = route(req)
  res.send(result) 
} catch (err) {
  if (err instanceof CustomError) {
    return res.status(err.status).send({
      error: err.code,
      description: err.message,
    })
  } else {
    console.error(err)
    return res.status(500).send({
      error: 'GENERIC',
      description: 'Something went wrong. Please try again or contact support.',
    })
  }
}

现在,你可以在代码中throw CustomeError错误信息

throw new CustomError('MY_CODE', 400, 'Error description')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant