Contents of this series

1. GlobalI went to see

2. Routes are matchedI went to see

3. Error Handling (this article)

4. View templateI went to see

5. Design ideaI went to see


1. Error capture for common languages

1.1c: Return value in case of convention error, such as API function return NULL, -1, ‘\0’, etc

FILE *fp;
if( (fp=fopen("D:\\demo.txt"."rb") = =NULL) {printf("Fail to open file! \n");
    exit(0);  // Exit program (end program)
}
Copy the code

C + + 1.2: try… catch… catch… throw

try{statement group}catch(Exception type) {exception handling code}...catch(Exception type) {exception code}Copy the code

Java 1.3: try… catch… catch… finally throw

try{}catch(Exception type) {exception handling code}...catch(Exception type) {exception code}finally{}Copy the code

1.4. Go language: Put a specific bit of the return value

func test(n float64) (float64, error) {
    if n < 0 {
        return 0, errors.New("error")}/ / implementation
}
result, err:= test(- 1)
iferr ! =nil {
   fmt.Println(err)
}
Copy the code

Why should I look at error catching in other languages? On the one hand, it is the experience of trying to find error trapping in other languages. More importantly, javaScript is an interpreted language, and the underlying language is V8, which is C/C ++. Understanding their error trapping is very necessary to study why javaScript errors occur and how to catch them. Even at the syntactic level try… The catch.


2. Where might errors be reported?

When js error, an error object will be set up, originally this section is to think in the v8 source to find where the hell is js error notification to js language from the depth of the c + + layer, but in domestic v8 source this information it is hard to find, your this bad English see foreign articles have a batch of slow, to find the source code, look for a few hours, I can’t see why, so LET it go and come back to v8 later when I have time, so I can only talk about what could go wrong at the JS level

Js language level may be wrong place or quite unified, mainly in the following aspects

  • JSSyntax error, code exception
    • Compile phase error
    • Run-time error
  • AJAXAbnormal request
  • Static resource loading is abnormal
  • Promiseabnormal
  • Iframeabnormal
  • Cross-domain Script error
  • Crash and jam

Error handling is critical for a server framework. Back to the main topic, how are errors handled within Express


3. Express error handling

First of all we want to know, for a framework, the more wrong wrong is not the language itself, or some unexpected places an error, but the user, namely the developer illegal use of framework, the framework itself to custom error, this error using generally will have a devastating impact on the framework itself, so tell developers have to throw an error.

There are several types of errors within Express

3.1 Custom error: Attempts to reference non-existent attributes, methods, or objects

  • Some obsolete middleware
var removedMiddlewares = [
  'bodyParser'.'compress'.'cookieSession'.'session'.'logger'.'cookieParser'.'favicon'.'responseTime'.'errorHandler'.'timeout'.'methodOverride'.'vhost'.'csrf'.'directory'.'limit'.'multipart'.'staticCache'
]
removedMiddlewares.forEach(function (name) {
  Object.defineProperty(exports, name, {
    get: function () {
      throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
    },
    configurable: true
  });
});
Copy the code
  • Deprecated properties on an object
Object.defineProperty(this.'router', {
   get: function () {
      throw new Error('\'app.router\' is deprecated! \nPlease see the 3.x to 4.x migration guide for details on how to update your app.'); }});Copy the code

This misstatement is beyond reproach, do not exist, must cite failure

3.2 Custom error, ungrammatical use

  • Router. use has no incoming middleware function
var callbacks = flatten(slice.call(arguments, offset));
  if (callbacks.length === 0) {
    throw new TypeError('Router.use() requires a middleware function')}/ /...
if (typeoffn ! = ='function') {
    throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
}
Copy the code
  • Route. all no callback is passed
if (typeofhandle ! = ='function') {
      var type = toString.call(handle);
      var msg = 'Route.all() requires a callback function but got a ' + type
      throw new TypeError(msg);
 }
Copy the code

3.3 Errors may be reported when using the expansion package

  • decodeURIComponent
try {
   return decodeURIComponent(val);
} catch (err) {
   if (err instanceof URIError) {
      err.message = 'Failed to decode param \'' + val + '\' ';
      err.status = err.statusCode = 400;
   }
   throw err;
}
Copy the code

Also follow the catch only explicitly known error principle, code quality is free

  • parseUrl
// get pathname of request
function getPathname(req) {
  try {
    return parseUrl(req).pathname;
  } catch (err) {
    return undefined; }}Copy the code

3.4 An error occurs during middleware execution

Middleware execution is the most complex process of Express. There are many reasons for errors, such as middleware function execution error, matching layer error, etc. Internally, a layerError variable is uniformly used to represent such errors. Each time before the next middleware execution, check whether there are any errors, and terminate execution if there are any. And passes the error down until it is handled by a specialized error handler, like the Promise chain

Error capture of the process

 function next(err) {
    var layerError = err === 'route' ?
      null :
      err;
    // remove added slash
    if (slashAdded) {
      req.url = req.url.substr(1);
      slashAdded = false;
    }
    // restore altered req.url
    if(removed.length ! = =0) {
      req.baseUrl = parentUrl;
      req.url = protohost + removed + req.url.substr(protohost.length);
      removed = ' ';
    }

    // signal to exit router
    if (layerError === 'router') {
      setImmediate(done, null)
      return
    }
	//codes ....
 }
Copy the code

Layer that deals specifically with errors

Layer.prototype.handle_error = function handle_error(error, req, res, next) {
  var fn = this.handle;

  if(fn.length ! = =4) {
    // not a standard error handler
    return next(error);
  }

  try {
    fn(error, req, res, next);
  } catch(err) { next(err); }};Copy the code

4. To summarize

Error capture of Express is divided into frame-related errors and frame-independent errors. Frame-related errors will directly crash the framework, such as using improper syntax. Frame-independent errors are generally unexpected errors that occur during the execution of middleware flows and are handled by a special error-handle layer, such as the following

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') = = ='development' ? err : {};
  // render the error page
  res.status(err.status || 500);
  res.render('error');
});
Copy the code

reference

  1. C/C++ handling of errors
  2. How to gracefully handle front-end exceptions?