Skip to content

Outside Callspec

You can add your own Express middleware around mountSpec — for example a global rate limiter, a health check, or an app errorHandler. Callspec handles the RPC router. Your middleware handles the rest.

If that middleware should return the same error body as an RPC route ({ error, data? }), sendRouteFailureResponse is the escape hatch: call it when you have res.

WhereHow
Handler, authenticate, or handleUnhandledErrorReturn err.*. mountSpec writes the response.
Your middleware (you have res)Call sendRouteFailureResponse(res, failure).

Do not add express.json() or Express error middleware to the router passed to mountSpec — mountSpec already wires those for RPC. Add app-level middleware and your catch-all errorHandler on the Express app instead (see below).

typescript
import {err, sendRouteFailureResponse} from 'callspec';
app.use((req, res, next) => {
if (overLimit(req)) {
sendRouteFailureResponse(res, err.TOO_MANY_REQUESTS());
return;
}
next();
});
ExportWhen
sendRouteFailureResponse(res, failure)You have res and a RouteFailure
formatRouteFailureBody(failure)Same JSON without res
isRouteFailure(value)Narrow a helper return or next(err)
logRequestSame jsout-express request log on another router

Call sendRouteFailureResponse in the middleware that decided the failure. An app errorHandler can catch RouteFailure values that were passed to next:

typescript
if (isRouteFailure(err)) {
sendRouteFailureResponse(res, err);
return;
}

authenticate and handleUnhandledError still return values — see Error handling: mountSpec flow.