@athenna/http
Version:
The Athenna Http server. Built on top of fastify.
80 lines (79 loc) • 2.6 kB
JavaScript
/**
* @athenna/http
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { Log } from '@athenna/logger';
import { Is, Json, String } from '@athenna/common';
export class HttpExceptionHandler {
/**
* Error codes that should be ignored from logging.
*/
get ignoreCodes() {
return Config.get('http.logger.ignoreCodes', []);
}
/**
* Error statuses that should be ignored from logging.
*/
get ignoreStatuses() {
return Config.get('http.logger.ignoreStatuses', []);
}
/**
* The exception handler of all request handlers.
*/
async handle({ error, response }) {
let code = error.code;
if (error.code === undefined) {
code = error.name || 'E_INTERNAL_SERVER';
}
const body = {
statusCode: Json.copy(error.statusCode) || Json.copy(error.status) || 500,
code: String.toSnakeCase(code).toUpperCase(),
name: Json.copy(error.name),
message: Json.copy(error.message),
details: Json.copy(error.details),
stack: Json.copy(error.stack)
};
if (error.help) {
body.help = Json.copy(error.help);
}
const isInternalServerError = Is.Error(error) && !Is.Exception(error);
const isDebugMode = Config.is('app.debug', true);
if (isInternalServerError && !isDebugMode) {
body.code = 'E_INTERNAL_SERVER';
body.name = 'InternalServerException';
body.message = 'An internal server exception has occurred.';
delete body.details;
}
if (!isDebugMode) {
delete body.stack;
}
response.status(body.statusCode).send(body);
if (!this.canBeLogged(error)) {
return;
}
if (!Is.Exception(error)) {
error = error.toAthennaException();
}
if (Config.is('http.logger.prettifyException', true)) {
Log.channelOrVanilla('exception').error(await error.prettify());
return;
}
Log.channelOrVanilla('exception').error(error);
}
/**
* Return a boolean indicating if the error can be logged or not.
*/
canBeLogged(error) {
if (this.ignoreCodes.includes(error.code)) {
return false;
}
if (this.ignoreStatuses.includes(error.status || error.statusCode)) {
return false;
}
return true;
}
}