import type express from "express" import type { InvalidStateError, NotFoundError, NotLoggedInError, OptimisticConcurrencyException, UnauthorizedError, ValidationError } from "../../errors.js" import type { RequestContext } from "../RequestContext.js" import { logRequestError } from "./reportError.js" export function defaultBasicErrorHandler( _req: express.Request, res: express.Response, _requestContext: RequestContext, r2: Effect ) { return r2 .tapErrorCause(cause => cause.isFailure() ? logRequestError(cause) : Effect.unit) .catchTag("ValidationError", err => Effect(() => { res.status(400).send(err.errors) })) // final catch all; expecting never so that unhandled known errors will show up .catchAll((err: never) => Effect.logError( "Program error, compiler probably silenced, got an unsupported Error in Error Channel of Effect" + err ) .map(() => err as unknown) .flatMap(Effect.die) ) } const optimisticConcurrencySchedule = Schedule.once() && Schedule.recurWhile(a => a._tag === "OptimisticConcurrencyException") export function defaultErrorHandler( req: express.Request, res: express.Response, _: RequestContext, r2: Effect ) { const r3 = ( req.method === "PATCH" ? r2.retry(optimisticConcurrencySchedule) : r2 ) return r3 .tapErrorCause(cause => cause.isFailure() ? logRequestError(cause) : Effect.unit) .catchTag("ValidationError", err => Effect(() => { res.status(400).send(err.errors) })) .catchTag("NotFoundError", err => Effect(() => { res.status(404).send(err) })) .catchTag("NotLoggedInError", err => Effect(() => { res.status(401).send(err) })) .catchTag("UnauthorizedError", err => Effect(() => { res.status(403).send(err) })) .catchTag("InvalidStateError", err => Effect(() => { res.status(422).send(err) })) .catchTag("OptimisticConcurrencyException", err => Effect(() => { // 412 or 409.. https://stackoverflow.com/questions/19122088/which-http-status-code-to-use-to-reject-a-put-due-to-optimistic-locking-failure res.status(412).send(err) })) // final catch all; expecting never so that unhandled known errors will show up .catchAll((err: never) => Effect.logError( "Program error, compiler probably silenced, got an unsupported Error in Error Channel of Effect" + err ) .map(() => err as unknown) .flatMap(Effect.die) ) } export type SupportedErrors = | ValidationError | NotFoundError | NotLoggedInError | UnauthorizedError | InvalidStateError | OptimisticConcurrencyException