Xử lý error trong rest api nodejs
Tags: restapi, node, errors
Published: 2019-10-20 00:39:11

---
title: Xử lý error trong rest api nodejs
published: true
description: Xử lý error trong rest api nodejs
tags: restapi, node, error
cover_image: https://images.unsplash.com/photo-1543285198-3af15c4592ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=667&q=80
---
Tạo ra 1 middleware error cho việc xử lý lỗi.

## Xử lý middleware cho error
Tại nơi định nghĩa app cho express xử lý như sau:
- Import error từ middlewares đã được định nghĩa
`const error = require('../api/middlewares/error')`
- Bind app middleware tới instance của express:
```
// if error is not an instanceOf APIError, convert it.
// APIError là class có chứa cấu trúc lỗi
app.use(error.converter);

// catch 404 and forward to error handler
app.use(error.notFound);

// error handler, send stacktrace only during development
app.use(error.handler);
```
## Định nghĩa APIError class
- Tạo file APIError.js chẳng hạn tại `src/api/utils/APIError.js`
- Nội dung file như sau
```
/* eslint-disable max-classes-per-file */
const httpStatus = require('http-status');

/**
 * @extends Error
 */
class ExtendableError extends Error {
  constructor({
 message, errors, status, isPublic, stack 
}) {
    super(message);
    this.name = this.constructor.name;
    this.message = message;
    this.errors = errors;
    this.status = status;
    this.isPublic = isPublic;
    this.isOperational = true; // This is required since bluebird 4 doesn't append it anymore.
    this.stack = stack;
    // Error.captureStackTrace(this, this.constructor.name);
  }
}

/**
 * Class representing an API error.
 * @extends ExtendableError
 */
class APIError extends ExtendableError {
  /**
   * Creates an API error.
   * @param {string} message - Error message.
   * @param {number} status - HTTP status code of error.
   * @param {boolean} isPublic - Whether the message should be visible to user or not.
   */
  constructor({
    message,
    errors,
    stack,
    status = httpStatus.INTERNAL_SERVER_ERROR,
    isPublic = false,
  }) {
    super({
      message,
      errors,
      status,
      isPublic,
      stack,
    });
  }
}

module.exports = APIError;
```
## Xử lý error trong middleware
- Tạo file `error.js`, chẳng hạn như `src/api/middlewares/error.js`
- Nội dung xử lý như sau:
```
const httpStatus = require('http-status');
const expressValidation = require('express-validation');
const APIError = require('../utils/APIError');

/**
 * Error handler. Send stacktrace only during development
 * @public
 */
const handler = (err, req, res, next) => {
  const response = {
    code: err.status,
    message: err.message || httpStatus[err.status],
    errors: err.errors,
    stack: err.stack,
  };

  if (process.env !== 'development') {
    delete response.stack;
  }

  res.status(err.status);
  res.json(response);
};
exports.handler = handler;

/**
 * If error is not an instanceOf APIError, convert it.
 * @public
 */
exports.converter = (err, req, res, next) => {
  let convertedError = err;

  if (err instanceof expressValidation.ValidationError) {
    convertedError = new APIError({
      message: 'Validation Error',
      errors: err.errors,
      status: err.status,
      stack: err.stack,
    });
  } else if (!(err instanceof APIError)) {
    convertedError = new APIError({
      message: err.message,
      status: err.status,
      stack: err.stack,
    });
  }

  return handler(convertedError, req, res);
};

/**
 * Catch 404 and forward to error handler
 * @public
 */
exports.notFound = (req, res, next) => {
  const err = new APIError({
    message: 'Not found',
    status: httpStatus.NOT_FOUND,
  });
  return handler(err, req, res);
};

```