express-zod-api
Advanced tools
Comparing version 2.5.1 to 2.5.2
@@ -5,2 +5,9 @@ # Changelog | ||
### v2.5.2 | ||
- Fixed a bug due to which the API did not respond in case of an error within the `ResultHandler`. | ||
- In this case the `LastResortHandler` comes into play. | ||
- It sets the status code to `500` and sends out plain text with an error message. | ||
- It is not customizable yet, and it's meant to be kept very simple in case of JSON conversion errors. | ||
### v2.5.1 | ||
@@ -7,0 +14,0 @@ |
@@ -11,4 +11,6 @@ "use strict"; | ||
const zod_1 = require("zod"); | ||
const errors_1 = require("./errors"); | ||
const helpers_1 = require("./helpers"); | ||
const mime_1 = require("./mime"); | ||
const result_handler_1 = require("./result-handler"); | ||
class AbstractEndpoint { | ||
@@ -155,7 +157,9 @@ } | ||
if (e instanceof Error) { | ||
logger.error(`Result handler failure: ${e.message}.`); | ||
(0, result_handler_1.lastResortHandler)({ | ||
logger, response, | ||
error: new errors_1.ResultHandlerError(e.message, error) | ||
}); | ||
} | ||
// throw e; | ||
} | ||
}; | ||
//# sourceMappingURL=endpoint.js.map |
@@ -7,1 +7,7 @@ export declare class RoutingError extends Error { | ||
} | ||
export declare class ResultHandlerError extends Error { | ||
protected readonly originalError?: Error; | ||
constructor(message: string, originalError?: Error | null); | ||
hasOriginalError(): boolean; | ||
getOriginalErrorMessage(): string | undefined; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.OpenAPIError = exports.DependsOnMethodError = exports.RoutingError = void 0; | ||
exports.ResultHandlerError = exports.OpenAPIError = exports.DependsOnMethodError = exports.RoutingError = void 0; | ||
class RoutingError extends Error { | ||
@@ -13,2 +13,15 @@ } | ||
exports.OpenAPIError = OpenAPIError; | ||
class ResultHandlerError extends Error { | ||
constructor(message, originalError) { | ||
super(message); | ||
this.originalError = originalError || undefined; | ||
} | ||
hasOriginalError() { | ||
return this.originalError !== undefined; | ||
} | ||
getOriginalErrorMessage() { | ||
return this.originalError ? this.originalError.message : undefined; | ||
} | ||
} | ||
exports.ResultHandlerError = ResultHandlerError; | ||
//# sourceMappingURL=errors.js.map |
@@ -5,3 +5,9 @@ import { Request, Response } from 'express'; | ||
import { ApiResponse } from './api-response'; | ||
import { ResultHandlerError } from './errors'; | ||
import { IOSchema } from './helpers'; | ||
interface LastResortHandlerParams { | ||
error: ResultHandlerError; | ||
logger: Logger; | ||
response: Response; | ||
} | ||
interface ResultHandlerParams<RES> { | ||
@@ -59,2 +65,3 @@ error: Error | null; | ||
}>>>; | ||
export declare const lastResortHandler: ({ error, logger, response }: LastResortHandlerParams) => void; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defaultResultHandler = exports.createResultHandler = void 0; | ||
exports.lastResortHandler = exports.defaultResultHandler = exports.createResultHandler = void 0; | ||
const zod_1 = require("zod"); | ||
@@ -41,2 +41,8 @@ const api_response_1 = require("./api-response"); | ||
}); | ||
const lastResortHandler = ({ error, logger, response }) => { | ||
logger.error(`Result handler failure: ${error.message}.`); | ||
response.status(500).end(`An error occurred while serving the result: ${error.message}.` + | ||
(error.hasOriginalError() ? `\nOriginal error: ${error.getOriginalErrorMessage()}.` : '')); | ||
}; | ||
exports.lastResortHandler = lastResortHandler; | ||
//# sourceMappingURL=result-handler.js.map |
/// <reference types="node" /> | ||
import { ErrorRequestHandler, RequestHandler } from 'express'; | ||
import { Server } from 'http'; | ||
import { Logger } from 'winston'; | ||
import { AppConfig, CommonConfig, ServerConfig } from './config-type'; | ||
import { Routing } from './routing'; | ||
export declare const createParserFailureHandler: (errorHandler: import("./result-handler").ResultHandlerDefinition<any, any>, logger: Logger) => ErrorRequestHandler; | ||
export declare const createNotFoundHandler: (errorHandler: import("./result-handler").ResultHandlerDefinition<any, any>, logger: Logger) => RequestHandler; | ||
export declare function attachRouting(config: AppConfig & CommonConfig, routing: Routing): void; | ||
export declare function createServer(config: ServerConfig & CommonConfig, routing: Routing): Server; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -6,5 +25,6 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createServer = exports.attachRouting = void 0; | ||
const express_1 = __importDefault(require("express")); | ||
exports.createServer = exports.attachRouting = exports.createNotFoundHandler = exports.createParserFailureHandler = void 0; | ||
const express_1 = __importStar(require("express")); | ||
const express_fileupload_1 = __importDefault(require("express-fileupload")); | ||
const errors_1 = require("./errors"); | ||
const helpers_1 = require("./helpers"); | ||
@@ -15,2 +35,32 @@ const logger_1 = require("./logger"); | ||
const http_errors_1 = __importDefault(require("http-errors")); | ||
const createParserFailureHandler = (errorHandler, logger) => (error, request, response, next) => { | ||
if (!error) { | ||
return next(); | ||
} | ||
errorHandler.handler({ | ||
error, request, response, logger, | ||
input: request.body, | ||
output: null | ||
}); | ||
}; | ||
exports.createParserFailureHandler = createParserFailureHandler; | ||
const createNotFoundHandler = (errorHandler, logger) => (request, response) => { | ||
const error = (0, http_errors_1.default)(404, `Can not ${request.method} ${request.path}`); | ||
try { | ||
errorHandler.handler({ | ||
request, response, logger, error, | ||
input: null, | ||
output: null | ||
}); | ||
} | ||
catch (e) { | ||
if (e instanceof Error) { | ||
(0, result_handler_1.lastResortHandler)({ | ||
response, logger, | ||
error: new errors_1.ResultHandlerError(e.message, error) | ||
}); | ||
} | ||
} | ||
}; | ||
exports.createNotFoundHandler = createNotFoundHandler; | ||
function attachRouting(config, routing) { | ||
@@ -25,3 +75,3 @@ const logger = (0, helpers_1.isLoggerConfig)(config.logger) ? (0, logger_1.createLogger)(config.logger) : config.logger; | ||
const errorHandler = config.errorHandler || result_handler_1.defaultResultHandler; | ||
const jsonParser = config.server.jsonParser || express_1.default.json(); | ||
const jsonParser = config.server.jsonParser || (0, express_1.json)(); | ||
const multipartParser = config.server.upload ? (0, express_fileupload_1.default)({ | ||
@@ -32,24 +82,6 @@ ...(typeof config.server.upload === 'object' ? config.server.upload : {}), | ||
}) : undefined; | ||
const parserFailureHandler = (error, request, response, next) => { | ||
if (!error) { | ||
return next(); | ||
} | ||
errorHandler.handler({ | ||
error, request, response, logger, | ||
input: request.body, | ||
output: null | ||
}); | ||
}; | ||
const lastResortHandler = (request, response) => { | ||
errorHandler.handler({ | ||
request, response, logger, | ||
error: (0, http_errors_1.default)(404, `Can not ${request.method} ${request.path}`), | ||
input: null, | ||
output: null | ||
}); | ||
}; | ||
app.use([jsonParser].concat(multipartParser || [])); | ||
app.use(parserFailureHandler); | ||
app.use((0, exports.createParserFailureHandler)(errorHandler, logger)); | ||
(0, routing_1.initRouting)({ app, routing, logger, config }); | ||
app.use(lastResortHandler); | ||
app.use((0, exports.createNotFoundHandler)(errorHandler, logger)); | ||
return app.listen(config.server.listen, () => { | ||
@@ -56,0 +88,0 @@ logger.info(`Listening ${config.server.listen}`); |
{ | ||
"name": "express-zod-api", | ||
"version": "2.5.1", | ||
"version": "2.5.2", | ||
"description": "A Typescript library to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -310,2 +310,5 @@ # Express Zod API | ||
Please note: `ResultHandler` must handle any errors and not throw its own. Otherwise, the case will be passed to the | ||
`LastResortHandler`, which will set the status code to `500` and send the error message as plain text. | ||
## Non-object response | ||
@@ -312,0 +315,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
147811
1499
529