Home > Software engineering >  Express.js API robust error handling solution
Express.js API robust error handling solution

Time:03-29

I'm trying to improve my code below with error handling such that I can use the error handling code else where in my application where it's relevant.

I have the following sequence of events:

Route handler --> middleware --> service --> DAO --> MongoDB

I want to implement a robust error handling solution that I can use throughout the application.

I ran into an issues where when DB is down or CRUD operation fails, DAO does not handle the error and propagate it to relevant levels. I certainly need to be able handle HTTP 500 type errors so that my API is robust. Any suggestions highly appreciated.

CodePudding user response:

As someone who ran into such "robust error-handling solutions" a few times (usually implemented as a middleware) I highly recommend against it:

Different routes will experience different edge cases which you'll want to handle separately. Trying to create a "silver bullet" that will handle everything will be inherently more complex and more difficult to maintain.

Further, due to the async nature of many routes, you may find yourself reading stacktraces of that error-handler without having the context of which route triggered it...

CodePudding user response:

Yes, you can improve your code and use a centralised error handler in case something goes wrong and the error is not already handled in your controller.

Let us create a simple app to understand the code flow and centralised error handling. Please note that I am writing the below code in StackOverflow editor hence running it directly might give syntax errors.

|- src
|-- app.js
|-- controller
|-- middleware
|-- routes

app.js

const express = require("express");
const routes = require("./routes");

const app = express();

// use /api endpoint for backend routes
app.use("/api", routes);

app.listen(8080);

middleware/error.js


function errorHandler(err, req, res, next) {
  console.log("some error has occurred");
  res.status(503).json({
    msg: "something went wrong"
  });
}

module.exports = errorHandler;

route/index.js

const express = require("express");
const router = express.Router();
const errorHandler = require("./middleware/error");
const HelloController = require("./controller/Hello.js");

router.route("/hello", HelloController);

router.use(errorHandler);

module.exports = router;

controller/Hello.js

function HelloController(req, res, next) {
  try {
    // Do some stuff, call dao
    // Any Special Error Handling will go here
    res.json({ msg: "success" });
  } catch (e) {
    // Any other error will call the errorHandler and send the 503 to the client thus preventing the
    // server to crash
    next(e); // this will call the errorHandler
  }
}

module.exports = HelloController;

The request flow will be as follows

App.Js -> route/index.js -> controller/Hello.js -> IF error in controller a) middleware/error.js, else b) exit

You can add more categorisation in your code based on routes like /api/public, /api/private, /api/admin

  • Related