gx-node-api-errors
Version:
Library to use in node js APIs to handle errors
169 lines (151 loc) • 4.21 kB
JavaScript
const parseJoiError = require('./errors/translateJoiError')
let customErrorCatalog = null;
let customMicroserviceName = null;
const Sentry = require('@sentry/node');
class AppError extends Error {
constructor(errorData) {
super();
Error.captureStackTrace(this, this.constructor);
Object.assign(this, errorData);
this.errors = this.getErrors();
this.statusCode = this.statusCode || 500;
this.name = this.constructor.name;
}
toJson() {
return {
message: this.message,
errors: this.errors,
microservice: errorsCatalog.get().customMicroserviceName,
};
}
getErrors() {
if (this.errors) {
return this.errors.details.map((error) => parseJoiError(error));
}
return this.parseError();
}
parseError() {
if (!this.errorCode) {
return [];
}
const errorsData = errorsCatalog.get().customErrorCatalog[this.errorCode]
errorsData.errorMessage = this.dynamicFields
? this.replaceDynamicFields(errorsData.errorMessage)
: errorsData.errorMessage;
return [
{
field: this.field,
fieldValue: this.fieldValue,
...errorsData,
},
];
}
replaceDynamicFields(message) {
let msg = message;
for (let i = 0; i < this.dynamicFields.length; i += 1) {
msg = msg.replace('fieldValue', this.dynamicFields[i]);
}
return msg;
}
}
class NotFoundError extends AppError {
constructor(message, field, fieldValue, errorCode) {
super({
message,
statusCode: 404,
field,
fieldValue,
errorCode,
});
}
}
class BadRequestError extends AppError {
constructor(message, field, fieldValue, errorCode) {
super({
message,
statusCode: 400,
field,
fieldValue,
errorCode,
});
}
}
class ValidationError extends AppError {
constructor(message, errors) {
super({ message, statusCode: 422, errors });
}
}
class UnprocessableEntityError extends AppError {
constructor(message, field, fieldValue, errorCode, dynamicFields = null) {
super({
message,
statusCode: 422,
field,
fieldValue,
errorCode,
dynamicFields,
});
}
}
class ValidationErrorForJoi extends AppError {
constructor(message, errors) {
super({ message, statusCode: 400, errors });
}
}
class DbError extends AppError {
constructor(message) {
super({ message, statusCode: 500 });
}
}
class ExternalServiceError extends AppError {
constructor(message) {
super({ message, statusCode: 500 });
}
}
class ExternalMicroserviceError extends AppError {
constructor(response) {
super({ message: 'The application has encountered an unknown error', statusCode: 500 })
this.logErrorToSentry(this, response)
}
logErrorToSentry(error, response) {
if (process.env.NODE_ENV !== "test") {
Sentry.captureException(error, {
extra: {
extServiceHttpCode: response.status,
data: JSON.stringify(response.data),
},
tags: {
source_microservice: errorsCatalog.get().customMicroserviceName,
target_microservice: response.data.microservice,
},
})
}
}
}
class AuthorizationError extends AppError{
constructor(){
super({ message: 'Unauthorized', statusCode: 401 })
}
}
const errorsCatalog = {
set: function (catalog, microservice) {
customErrorCatalog = catalog;
customMicroserviceName = microservice;
},
get: function () {
return {
customMicroserviceName,
customErrorCatalog
}
}
}
exports.AuthorizationError = AuthorizationError;
exports.BadRequestError = BadRequestError;
exports.DbError = DbError;
exports.errorsCatalog = errorsCatalog;
exports.ExternalServiceError = ExternalServiceError;
exports.ExternalMicroserviceError = ExternalMicroserviceError;
exports.NotFoundError = NotFoundError;
exports.UnprocessableEntityError = UnprocessableEntityError;
exports.ValidationError = ValidationError;
exports.ValidationErrorForJoi = ValidationErrorForJoi;