Skip to content

Commit

Permalink
feat: enable registration of error-handler plugin (#710)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrians5j authored Feb 11, 2020
1 parent cab83c8 commit 21f586e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
36 changes: 22 additions & 14 deletions packages/http-handler/src/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import {
HttpAfterHandlerPlugin,
HttpBeforeHandlerPlugin,
HttpContextPlugin,
HttpHandlerPlugin
HttpHandlerPlugin,
HttpErrorHandlerPlugin
} from "./types";

export default (...plugins) => async (...args) => {
try {
const context = {
plugins: new PluginsContainer(plugins)
};
const context = {
plugins: new PluginsContainer(plugins)
};

try {
const contextPlugins = context.plugins.byType<HttpContextPlugin>("context");
for (let i = 0; i < contextPlugins.length; i++) {
contextPlugins[i].apply({ context, args });
Expand All @@ -23,33 +24,40 @@ export default (...plugins) => async (...args) => {
await beforeHandlers[i].handle({ context, args });
}

let result;
let result, handled;
const handlers = context.plugins.byType<HttpHandlerPlugin>("handler");
for (let i = 0; i < handlers.length; i++) {
const handler = handlers[i];
if (handler.canHandle({ context, args })) {
result = await handler.handle({ context, args });
handled = true;
break;
}
}

if (!handled) {
throw new Error("Not a single handler could handle the request.");
}

const afterHandlers = context.plugins.byType<HttpAfterHandlerPlugin>("after-handler");
for (let i = 0; i < afterHandlers.length; i++) {
await afterHandlers[i].handle({ context, args, result });
}

if (!result) {
return createResponse({
body: "Request not handled. Please check registered handlers."
});
return result;
} catch (error) {
const handlers = context.plugins.byType<HttpErrorHandlerPlugin>("error-handler");
for (let i = 0; i < handlers.length; i++) {
const handler = handlers[i];
if (handler.canHandle({ context, args, error })) {
return handler.handle({ context, args, error });
}
}

return result;
} catch (e) {
// TODO: Make optional and pluginable.
return createResponse({
statusCode: 404,
type: "text/html",
body: `<html><h1>An error occurred</h1><p>${e.stack}</p></html>`,
body: `<html><h1>An error occurred</h1><p>${error.stack}</p></html>`,
headers: { "Cache-Control": "no-store" }
});
}
Expand Down
6 changes: 6 additions & 0 deletions packages/http-handler/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export type HttpHandlerPlugin = Plugin & {
handle(params: { context: HttpContext; args: HttpArgs }): Promise<any>;
};

export type HttpErrorHandlerPlugin = Plugin & {
type: "error-handler";
canHandle(params: { context: HttpContext; args: HttpArgs; error: any }): boolean;
handle(params: { context: HttpContext; args: HttpArgs; error: any }): Promise<any>;
};

export type HttpAfterHandlerPlugin = Plugin & {
type: "after-handler";
handle(params: { context: HttpContext; args: HttpArgs; result: any }): Promise<void>;
Expand Down

0 comments on commit 21f586e

Please sign in to comment.