import * as _ from "lodash"; import * as Hapi from "hapi"; import { Bundle, App, LogLevel } from "protoculture"; import { Route, ActionRoute, DirectoryRoute, FileRoute } from "./Route"; import { Handler } from "./Handler"; export class Dispatcher { public constructor(protected app: App) { } // Note: This is the root async context. public async dispatch(request: Hapi.Request, reply: Hapi.Base_Reply, route: ActionRoute, symbol: symbol) { const childContainer = await this.app.bundle.bootChild(); const actionTarget = childContainer.get(symbol); const action: Handler = actionTarget[route.actionMethod] || actionTarget; try { await action(request, reply, route); } catch (error) { // ToDo: Certain types of automatic responses could be generated by catching here and forwarding to an error handler. this.error(error, request, reply, route); } } protected error(error: any, request: Hapi.Request, reply: Hapi.Base_Reply, route: Route) { if (_.isError(error)) { const {name, message, stack} = error; request.log(["error", "uncaught"], {name, message, stack}); } else { request.log(["error", "uncaught"], {name: "Error", message: error}); error = new Error(error); } reply(error); } }