types for error handler

This commit is contained in:
Dan Ribbens
2020-12-01 09:46:57 -05:00
parent bb7c829c5e
commit 6b61714d7e
5 changed files with 16 additions and 16 deletions

View File

@@ -127,7 +127,7 @@ export type PayloadConfig = {
components?: { [key: string]: JSX.Element | (() => JSX.Element) };
paths?: { [key: string]: string };
hooks?: {
afterError?: (err: Error, res: unknown) => { response: unknown, status: number} | unknown;
afterError?: (err: Error, res: unknown) => { response: any, status: number } | void;
};
webpack?: (config: Configuration) => Configuration;
serverModules?: string[];

View File

@@ -7,13 +7,13 @@ import httpStatus from 'http-status';
class ExtendableError extends Error {
status: number;
data: any;
data: {[key: string]: unknown};
isPublic: boolean;
isOperational: boolean;
constructor(message: string, status: number, data: any, isPublic: boolean) {
constructor(message: string, status: number, data: { [key: string]: unknown }, isPublic: boolean) {
super(message);
this.name = this.constructor.name;
this.message = message;
@@ -39,7 +39,7 @@ class APIError extends ExtendableError {
* @param {object} data - response data to be returned.
* @param {boolean} isPublic - Whether the message should be visible to user or not.
*/
constructor(message: string, status: number = httpStatus.INTERNAL_SERVER_ERROR, data: any = null, isPublic = false) {
constructor(message: string, status: number = httpStatus.INTERNAL_SERVER_ERROR, data: { [key: string]: unknown } = null, isPublic = false) {
super(message, status, data, isPublic);
}
}

View File

@@ -1,28 +1,26 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import httpStatus from 'http-status';
import { Response, NextFunction } from 'express';
import { Logger } from 'pino';
import { Config } from '../../config/types';
import formatErrorResponse, { ErrorResponse } from '../responses/formatError';
import { PayloadRequest } from '../types/payloadRequest';
import APIError from '../../errors/APIError';
export type ErrorHandler = (err: Error, req: PayloadRequest, res: Response, next: NextFunction) => Promise<Response<ErrorResponse>>
// NextFunction must be passed for Express to use this middleware as error handler
const errorHandler = (config: Config, logger) => async (err: Error, req: PayloadRequest, res: Response, next: NextFunction): Promise<void> => {
const data = formatErrorResponse(err);
const errorHandler = (config: Config, logger: Logger) => async (err: APIError, req: PayloadRequest, res: Response, next: NextFunction): Promise<void> => {
const errorResponse = formatErrorResponse(err);
let response;
let status = err.status || httpStatus.INTERNAL_SERVER_ERROR;
logger.error(err.stack);
if (config.debug && config.debug === true) {
data.stack = err.stack;
errorResponse.stack = err.stack;
}
response = {
...data,
};
if (typeof config.hooks.afterError === 'function') {
({ response, status } = await config.hooks.afterError(err, response) || { response, status });
}

View File

@@ -1,8 +1,10 @@
export type ErrorResponse = unknown;
import APIError from '../../errors/APIError';
const formatErrorResponse = (incoming) => {
export type ErrorResponse = { errors: unknown[], data?: any, stack?: string };
const formatErrorResponse = (incoming: Error | APIError | { [key: string]: unknown }): ErrorResponse => {
if (incoming) {
if (incoming && incoming.data && incoming.data.length > 0) {
if (incoming instanceof APIError && incoming.data && incoming.data.length > 0) {
return {
errors: [{
name: incoming.name,
@@ -13,7 +15,7 @@ const formatErrorResponse = (incoming) => {
}
// mongoose
if (incoming.errors) {
if (!(incoming instanceof APIError || incoming instanceof Error) && incoming.errors) {
return {
errors: Object.keys(incoming.errors)
.reduce((acc, key) => {

View File

@@ -135,7 +135,7 @@ export class Payload {
}
// Configure email service
this.email = buildEmail(this.config.email);
this.email = buildEmail(this.emailOptions);
// Initialize collections & globals
initCollections(this);