@algoan/nestjs-http-exception-filter
Version:
A simple http exception filter for NestJS applications
95 lines • 9.03 kB
JavaScript
;
var HttpExceptionFilter_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpExceptionFilter = void 0;
const tslib_1 = require("tslib");
const common_1 = require("@nestjs/common");
const lodash_1 = require("lodash");
const error_utils_1 = require("./error.utils");
let HttpExceptionFilter = HttpExceptionFilter_1 = class HttpExceptionFilter {
constructor(options) {
var _a, _b, _c;
this.logger = new common_1.Logger(HttpExceptionFilter_1.name);
this.disableMasking = (_a = options === null || options === void 0 ? void 0 : options.disableMasking) !== null && _a !== void 0 ? _a : false;
this.maskingPlaceholder = (_b = options === null || options === void 0 ? void 0 : options.maskingPlaceholder) !== null && _b !== void 0 ? _b : '****';
this.mask = (_c = options === null || options === void 0 ? void 0 : options.mask) !== null && _c !== void 0 ? _c : {};
}
catch(exception, host) {
const ctx = host.switchToHttp();
const request = ctx.getRequest();
const response = ctx.getResponse();
let status;
if (exception instanceof common_1.HttpException) {
status = exception.getStatus();
}
else {
const type = (0, lodash_1.get)(exception, 'type');
status = type === 'entity.too.large' ? common_1.HttpStatus.PAYLOAD_TOO_LARGE : common_1.HttpStatus.INTERNAL_SERVER_ERROR;
}
let code = exception instanceof common_1.HttpException
? (0, error_utils_1.getCode)(exception.getResponse())
: common_1.HttpStatus[common_1.HttpStatus.INTERNAL_SERVER_ERROR];
let message = exception instanceof common_1.HttpException
? (0, error_utils_1.getErrorMessage)(exception.getResponse())
: 'An internal server error occurred';
if (status === common_1.HttpStatus.PAYLOAD_TOO_LARGE) {
code = common_1.HttpStatus[common_1.HttpStatus.PAYLOAD_TOO_LARGE];
message = `
Your request entity size is too big for the server to process it:
- request size: ${(0, lodash_1.get)(exception, 'length')};
- request limit: ${(0, lodash_1.get)(exception, 'limit')}.`;
}
const exceptionStack = 'stack' in exception ? exception.stack : '';
if (status >= common_1.HttpStatus.INTERNAL_SERVER_ERROR) {
this.logger.error({
message: `${status} [${request.method} ${request.url}] has thrown a critical error`,
headers: this.maskHeaders(request.headers),
}, exceptionStack);
}
else if (status >= common_1.HttpStatus.BAD_REQUEST) {
this.logger.warn({
message: `${status} [${request.method} ${request.url}] has thrown an HTTP client error`,
exceptionStack,
headers: this.maskHeaders(request.headers),
});
}
response.status(status).send({
code,
message,
status,
});
}
maskHeaders(headers) {
var _a;
if (this.disableMasking || ((_a = this.mask) === null || _a === void 0 ? void 0 : _a.requestHeader) === undefined) {
return headers;
}
return Object.keys(headers).reduce((maskedHeaders, headerKey) => {
var _a, _b;
const headerValue = headers[headerKey];
const mask = (_b = (_a = this.mask) === null || _a === void 0 ? void 0 : _a.requestHeader) === null || _b === void 0 ? void 0 : _b[headerKey];
if (headerValue === undefined) {
return maskedHeaders;
}
if (mask === true) {
return Object.assign(Object.assign({}, maskedHeaders), { [headerKey]: this.maskingPlaceholder });
}
if (typeof mask === 'function') {
try {
return Object.assign(Object.assign({}, maskedHeaders), { [headerKey]: mask(headerValue) });
}
catch (error) {
this.logger.warn(`HttpFilterOptions - Masking error for header ${headerKey}`, { error, mask, headerKey });
return Object.assign(Object.assign({}, maskedHeaders), { [headerKey]: this.maskingPlaceholder });
}
}
return maskedHeaders;
}, headers);
}
};
exports.HttpExceptionFilter = HttpExceptionFilter;
exports.HttpExceptionFilter = HttpExceptionFilter = HttpExceptionFilter_1 = tslib_1.__decorate([
(0, common_1.Catch)(),
tslib_1.__metadata("design:paramtypes", [Object])
], HttpExceptionFilter);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1leGNlcHRpb24tZmlsdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2h0dHAtZXhjZXB0aW9uLWZpbHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDJDQUEwRztBQUcxRyxtQ0FBNkI7QUFDN0IsK0NBQXlEO0FBa0RsRCxJQUFNLG1CQUFtQiwyQkFBekIsTUFBTSxtQkFBbUI7SUFPOUIsWUFBWSxPQUFvQzs7UUFOL0IsV0FBTSxHQUFXLElBQUksZUFBTSxDQUFDLHFCQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBT3JFLElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsY0FBYyxtQ0FBSSxLQUFLLENBQUM7UUFDdkQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE1BQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLGtCQUFrQixtQ0FBSSxNQUFNLENBQUM7UUFDaEUsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxJQUFJLG1DQUFJLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBTU0sS0FBSyxDQUFDLFNBQWMsRUFBRSxJQUFtQjtRQUM5QyxNQUFNLEdBQUcsR0FBc0IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ25ELE1BQU0sT0FBTyxHQUFZLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxQyxNQUFNLFFBQVEsR0FBYSxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDN0MsSUFBSSxNQUFjLENBQUM7UUFFbkIsSUFBSSxTQUFTLFlBQVksc0JBQWEsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sR0FBRyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakMsQ0FBQzthQUFNLENBQUM7WUFFTixNQUFNLElBQUksR0FBdUIsSUFBQSxZQUFHLEVBQUMsU0FBUyxFQUFFLE1BQU0sQ0FB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