Catching and Logging HTTP API Errors with Middleware

Hey everyone, is there a recommended way to catch all HTTP api errors in one area so they can be logged?

I have a few endpoints that can throw HTTP errors (e.g. InternalServerErrors). I'd like to be able to setup some middleware that can catch these errors and log them to the console or send them to Sentry without having to add Effect.catchTags to all effects that might throw. Is this possible?

Here's a contrived example of what I'm trying to do:

https://effect.website/play#b6f81e62de6c

import {
  HttpApiBuilder,
  HttpApiEndpoint,
  HttpApiGroup,
  HttpApi,
  HttpApiMiddleware,
} from "@effect/platform";
import { InternalServerError } from "@effect/platform/HttpApiError";
import { Effect, Schema, Layer } from "effect";

const DemoApiGroup = HttpApiGroup.make("Demo")
  .add(
    HttpApiEndpoint.post("demo")`/demo`
      .addError(InternalServerError)
      .addSuccess(Schema.Struct({
        status: Schema.String,
      })),
  );

class ErrorLogMiddleware extends HttpApiMiddleware.Tag<ErrorLogMiddleware>()(
  "ErrorLogMiddleware"
) { }

const ErrorLogMiddlewareLive = Layer.effect(
  ErrorLogMiddleware,
  Effect.gen(function* () {
    return Effect.gen(function* () {
      // Log and catch all errors here
    })
  }),
)

const Api = HttpApi.make("Api")
  .add(DemoApiGroup.middleware(ErrorLogMiddleware))

const createDemoRouteHandler = () =>
  HttpApiBuilder.group(Api, "Demo", (handlers) =>
    Effect.gen(function* () {
      return handlers
        .handle("demo", () =>
          Effect.gen(function* () {
            return yield* Effect.fail(new InternalServerError())
          })
        )
    })
  );

export const ApiLive = HttpApiBuilder.api(Api).pipe(
  Layer.provide(createDemoRouteHandler()),
  Layer.provide(ErrorLogMiddlewareLive),
);
Was this page helpful?