异常处理

JavaScript 中的异常处理

异常类型

  • Syntax Error: Your code won’t parse. Translation: You have a typo. Solutions: i) go check that line number. (see also: your linter) ii) know that a syntax error will be generated by the line where the code itself breaks — often the actual typo might be in the lines above (or below, if you have a brackets problem)

  • TypeError: your code expects a variable to be one kind of thing, but it is in fact another. This is one that you’ll see a lot, because it can be caused by lots of different kinds of screw ups. error messages like “cannot read {property} of undefined” or “{such and such} is not a function” are generally type errors. This is a very non-exhuastive list of solutions, to give you an idea of where to start looking. i ) console.log(typeof offendingVariable) to see if it’s what you expect/need. ii) check the formatting of your function — is it being called on what it should be called on, is it structured correctly? iii) is your data moving where it should? (console.log your function arguments and maybe their types?) iv) if this error is being thrown by your use of a library, check the docs to see if you’re using it right. ivA) try to find examples of other people using that tool!

  • ReferenceError: You’re referencing a variable that does not exist. Solution: look for where you think you’ve defined it, or where you should have defined it. you will likely find that you have either a) made a typo, b) imported/exported incorrectly c) not actually declared it at all or d) made a scoping error (eg, using “let” inside an “if” block, and then referencing that variable outside the code block). Solution: look for where you think you’ve defined it, or where you should have defined it. you will likely find that you have either a) made a typo, b) imported/exported incorrectly c) not actually declared it at all or d) made a scoping error (eg, using “let” inside an “if” block, and then referencing that variable outside the code block).

  • RangeError: Raised when a numeric variable exceeds its allowed range (solution: don’t do complicated math in javascript. or at least, use a special math-y library for it. alternately: fix your callstack.)

  • EvalError: you’re using eval() wrong. but if you get this error, you *know *you’re using eval() wrong, because you’ve decided to use eval(). Don’t do that.

  • URIError: Raised when the encodeURI() or decodeURI() functions are used in an incorrect manner. Lots of cool libraries exist just so that you never have to make this error. Like Express. Or Koa. Or Hapi. Consider using one.

Promise 与事件中的异常

(node:48446) UnhandledPromiseRejectionWarning: This is fine
(node:48446) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:48446) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

The process doesn’t crash. The process continues to work. But you get noticed. However, this behavior will change in the future! In future versions of Node.js the process will crash.

process.on("unhandledRejection", (reason, promise) => {
  console.log("Unhandled Rejection at:", reason.stack || reason);
  // Recommended: send the information to sentry.io
  // or whatever crash reporting service you use
});

For promises rejected with an error (e.g. Promise.reject(new Error(‘This is fine’))) this will print both the message and the stack trace. In any other case this will print the object passed to reject the promise. So, it is important to always reject with an error object in order to get a stack trace!

const fs = require('fs');
const stream = fs.createReadStream('do-not-exists.txt')

// Output
events.js:137
      throw er; // Unhandled 'error' event
      ^
Error: ENOENT: no such file or directory, open 'do-not-exists.txt'

Always handle promise rejections. Listen to unhandled rejection events for crash reporting. And always use errors to reject promises in order to get stack traces!

Always handle the error event for streams! Wrap JSON.parse() and any*Sync() function in a

try-catch block or inside a Promise. Well, in general any function that can throw errors.

上一页