Suvidha handlers are essential for customizing request processing. They handle validation, responses, and more.

All handlers receive a Conn object, which contains the following:

  • req: An extended Express’ Request object, which includes the context. property for accessing request-specific data added by middlewares.
  • res: The standard Express Response object.
/**
 * CtxRequest adds context to the Express' Request object
 * CtxRequest<Context, Params, ResBody, ReqBody, ReqQuery>,
 * Request<            Params, ResBody, ReqBody, ReqQuery>
 */
export type Conn<T extends Context, ...> = {
    req: CtxRequest<T, ...>;
    res: Response;
};
class Suvidha {
    constructor(handlers: Handlers);
}

The Suvidha constructor takes any object that implements the Handlers interface, which is defined as follows:

export interface Handlers {
    onErr(err: unknown, conn: Conn, next: NextFunction): Promise<void> | void;
    onSchemaErr(
        err: ZodError,
        conn: Conn,
        next: NextFunction,
    ): Promise<void> | void;
    onComplete(
        output: unknown,
        conn: Conn,
        next: NextFunction,
    ): Promise<void> | void;
    onPostResponse(
        outputOrErr: unknown,
        conn: Conn,
        next: NextFunction,
    ): Promise<void> | void;
}

Understanding the Handlers

Here’s a breakdown of each handler:

Example Implementation

class CustomHandlers implements Handlers {
    onSchemaErr(err: ZodError, conn: Conn, next: NextFunction) {
        console.error("Schema validation failed:", err.errors); // Log the errors
        conn.res.status(400).json({ error: "Invalid request data" }); // Send a 400 response
    }

    onErr(err: unknown, conn: Conn, next: NextFunction) {
        console.error("An error occurred:", err);
        conn.res.status(500).json({ error: "Internal server error" }); // Or call next(err)
    }

    onComplete(output: unknown, conn: Conn, next: NextFunction) {
        conn.res.json(output); // Send the output as JSON
    }

    onPostResponse(outputOrErr: unknown, conn: Conn, next: NextFunction) {
        if (outputOrErr instanceof Error) {
            // Check if it's an error
            console.error("Error after response:", outputOrErr);
            // You might not be able to send a *new* response here.
            // Log the error or perform cleanup tasks.
        } else {
            console.warn(
                "Request handler returned value after sending response:",
                outputOrErr,
            );
            // This is usually a bug. Log it and possibly take corrective action.
        }
    }
}

// Creating a Suvidha instance with custom handlers
const suvidha = () => new Suvidha(new CustomHandlers());

app.get(
    "/reports",
    suvidha().handler((req) => {
        // Business logic
    }),
);