wip api-v3: add error handler middleware and custom error classes

This commit is contained in:
Matteo Pagliazzi
2015-11-03 13:35:32 +01:00
parent b21df9edb3
commit 4322b8c3dc
4 changed files with 98 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
'use strict';
// Base class for custom application errors
// It extends Error and capture the stack trace
class CustomError extends Error {
constructor() {
super();
Error.captureStackTrace(this, this.constructor);
}
};
// NotAuthorized error with a 401 http error code
// used when a request is not authorized
class NotAuthorized extends CustomError {
constructor(customMessage) {
super();
this.name = this.constructor.name;
this.httpCode = 401;
this.message = customMessage || 'Not authorized.'
}
};
// BadRequest error with a 400 http error code
// used for requests not formatted correctly
// TODO use for validation errors too?
class BadRequest extends CustomError {
constructor(customMessage) {
super();
this.name = this.constructor.name;
this.httpCode = 400;
this.message = customMessage || 'Bad request.'
}
};
// InternalError error with a 500 http error code
// used when an unexpected, internal server error is thrown
class InternalServerError extends CustomError {
constructor(customMessage) {
super();
this.name = this.constructor.name;
this.httpCode = 500;
this.message = customMessage || 'Internal server error.'
}
};
module.exports = {
CustomError,
NotAuthorized,
BadRequest,
InternalServerError
};

View File

@@ -0,0 +1,33 @@
'use strict';
// The error handler middleware that handles all errors
// and respond to the client
let errors = require('../../libs/api-v3/errors');
let CustomError = errors.CustomError;
let InternalServerError = errors.InternalServerError;
module.exports = function (err, req, res, next) {
// TODO add logging
// In case of a CustomError class, use it's data
// Otherwise try to identify the type of error (mongoose validation, mongodb unique, ...)
// If we can't identify it, respond with a generic 500 error
let responseErr = err instanceof CustomError ? err : null;
if (!responseErr) {
// Try to identify the error...
// ...
// Otherwise create an InternalServerError and use it
// we don't want to leak anything, just a generic error message
responseErr = new InternalServerError();
}
return res
.status(responseErr.httpCode)
.json({
error: responseErr.name,
message: responseErr.message
});
};

View File

@@ -0,0 +1,11 @@
'use strict';
// This module is only used to attach middlewares to the express app
let errorHandler = require('./errorHandler');
module.exports = function (app) {
// Error handler middleware, define as the last one
app.use(errorHandler);
};

View File

@@ -104,6 +104,9 @@ if (cores!==0 && cluster.isMaster && (isDev || isProd)) {
// Matches all requests going to /api/v3 // Matches all requests going to /api/v3
app.all('/api/v3', newApp); app.all('/api/v3', newApp);
// Mount middlewares for the new app
require('./middlewares/api-v3/index')(newApp);
//require('./middlewares/apiThrottle')(oldApp); //require('./middlewares/apiThrottle')(oldApp);
oldApp.use(require('./middlewares/domain')(server,mongoose)); oldApp.use(require('./middlewares/domain')(server,mongoose));
if (!isProd && !DISABLE_LOGGING) oldApp.use(require('morgan')("dev")); if (!isProd && !DISABLE_LOGGING) oldApp.use(require('morgan')("dev"));