Skip to content

Commit

Permalink
Refactor error handling and response generation
Browse files Browse the repository at this point in the history
Add GenericResponse schema to documentation
  • Loading branch information
DanPlayz0 committed Jan 29, 2024
1 parent 1556b2f commit 281f406
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 10 deletions.
10 changes: 5 additions & 5 deletions src/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,25 +209,25 @@ export class Server<Context extends {}, Methods extends LocalRouteMethods<Contex
if (this.documentation) this.documentation.addRoute(route.configuration?.documentation, routePath, method);

const routeFunc = async (req: express.Request, res: express.Response, next: express.NextFunction) => {
const errorResponse = (status: HttpStatus, opts?: { message?: string; data?: any; code?: string }) => {
const respond = (status: HttpStatus, opts?: { error?: boolean, message?: string; data?: any; code?: string }) => {
return res
.status(status)
.send({ error: true, status: status, code: opts?.code || HttpStatus[status], message: opts?.message, data: opts?.data });
.send({ error: opts?.error ?? true, status: status, code: opts?.code || HttpStatus[status], message: opts?.message, data: opts?.data });
};

const variables = new Map();
for (let auth of routeMiddleware) {
let worked = false;
let goNext = () => (worked = true);
await auth.handle({ ...this.config.routes.context, req, res, next: goNext, errorResponse, variables }, auth.data);
await auth.handle({ ...this.config.routes.context, req, res, next: goNext, respond, variables }, auth.data);
if (worked == false) return;
}

try {
return route.handler({ ...this.config.routes.context, req, res, next, errorResponse, variables });
return route.handler({ ...this.config.routes.context, req, res, next, respond, variables });
} catch (error) {
log('error', (error as Error).message ?? 'Unknown error');
return errorResponse(HttpStatus.INTERNAL_SERVER_ERROR, {
return respond(HttpStatus.INTERNAL_SERVER_ERROR, {
message: (error as Error).message ?? 'Unknown error',
code: 'UNKNOWN_ROUTE_ERROR',
});
Expand Down
26 changes: 26 additions & 0 deletions src/documentation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ export default class Documentation {

this.operationIds = new Set();
this.schemaNames = new Set();

this.addSchema("GenericResponse", {
type: "object",
required: ["success", "code", "status"],
properties: {
error: {
type: "boolean",
description: "Whether the request errored."
},
status: {
type: "number",
description: "The HTTP status code.",
},
code: {
type: "string",
description: "The error code."
},
message: {
type: "string",
description: "The error message.",
},
data: {
description: "The validation error messages."
}
}
});
}

addSchema(name: string, schema: OpenAPI.SchemaObject, publicSchema = false) {
Expand Down
7 changes: 4 additions & 3 deletions src/types/httprouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,24 @@ export interface RouteConfig<Context extends {}, Methods extends LocalRouteMetho
documentation: Documentation;
}

export type ErrorResponse = (
export type GenericResponse = (
status: HttpStatus,
opts?: {
error?: boolean;
message?: string;
data?: any;
code?: string;
},
) => express.Response<any, Record<string, any>>;

export type ExpressErrorResponse = express.Response<any, Record<string, any>>;
export type ExpressGenericResponse = express.Response<any, Record<string, any>>;

export interface HTTPContext {
// HTTP Context
req: express.Request;
res: express.Response;
next: express.NextFunction;
errorResponse: ErrorResponse;
respond: GenericResponse;
variables: Map<string, any>;
}

Expand Down
4 changes: 2 additions & 2 deletions src/types/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import express from 'express';
import { ExpressErrorResponse, HTTPContext } from './httprouter';
import { ExpressGenericResponse, HTTPContext } from './httprouter';
import { APIInfoObject } from 'documentation';
import { WebSocketServer } from 'ws';

Expand All @@ -13,7 +13,7 @@ import { WebSocketServer } from 'ws';
export type CtxMiddlewareFunction<Context = {}, Data = any> = (
ctx: Context & HTTPContext,
data: Data,
) => (express.NextFunction | ExpressErrorResponse | void) | Promise<express.NextFunction | ExpressErrorResponse | void>;
) => (express.NextFunction | ExpressGenericResponse | void) | Promise<express.NextFunction | ExpressGenericResponse | void>;
export type MiddlewareFunction = (
req: express.Request,
res: express.Response,
Expand Down

0 comments on commit 281f406

Please sign in to comment.