Custom Handler (New)
Available since v1.6.0-beta
Arkos registers its global error handler automatically after app.build(). You can add your own error middleware right after that call — useful for sending errors to external monitoring services, custom logging sinks, or alerts.
Adding a Custom Handler
import arkos from "arkos";
import { ArkosRequest, ArkosResponse, ArkosNextFunction } from "arkos";
const app = arkos();
app.use(myRouter);
await app.build();
// Register your custom error handler here — after build, before listen
app.use((err: any, req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {
// Arkos has already sent the response — use this for side effects only
console.error("[CustomHandler]", err.message);
next(err);
});
app.listen();Your custom error handler must be registered after await app.build(). Registering it before build() places it before Arkos's error handler in the middleware chain — it will never receive errors from built-in routes since Arkos's handler runs first and sends the response without calling next(err).
Arkos's global error handler sends the response and does not call next(err). Your custom handler runs after it purely for side effects — do not call res.json() or res.send() inside it.
Use Cases
External Monitoring (Sentry)
import * as Sentry from "@sentry/node";
await app.build();
app.use((err: any, req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {
if (!err.isOperational) {
// Only report unexpected errors — not 404s, 403s, validation failures
Sentry.captureException(err);
}
next(err);
});
app.listen();Slack Alerts
await app.build();
app.use(async (err: any, req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {
if (err.statusCode >= 500) {
await slackClient.postMessage({
channel: "#alerts",
text: `[${req.method} ${req.path}] ${err.message}`,
});
}
next(err);
});
app.listen();Custom Logging
await app.build();
app.use((err: any, req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {
logger.error({
message: err.message,
code: err.code,
statusCode: err.statusCode,
path: req.path,
method: req.method,
userId: req.user?.id,
});
next(err);
});
app.listen();Always call next(err) at the end of your custom handler to keep the Express error chain intact.