Error Handling

Teasim catches all the errors thrown in the handler, classifies the error code, and pipes them to onError middleware.

new Teasim()
  .onError(({ code, error }) => {
    return new Response(error.toString());
  })
  .get("/", () => {
    throw new Error("Server is during maintainance");

    return "unreachable";
  });

With onError you can catch and transform the error into your custom error message.

TIP

It's important that onError must be called before the handler you want to apply it to.

For example, returning custom 404 messages:

import { Teasim, NotFoundError } from "teasim";

new Teasim()
  .onError(({ code, error, set }) => {
    if (code === "NOT_FOUND") {
      set.status = 404;

      return "Not Found :(";
    }
  })
  .post("/", () => {
    throw new NotFoundError();
  })
  .listen(8080);

Local Error

You can assign an error handling method to a scope using hook or guard

app.get("/", () => "Hello", {
  beforeHandle({ set, request: { headers } }) {
    if (!isSignIn(headers)) {
      set.status = 401;

      throw new Error("Unauthorized");
    }
  },
  error({ error }) {
    return "Handled";
  },
});

Custom Error Message

You can provide a custom error message by providing error:

new Teasim().post("/", ({ body }) => body, {
  body: t.Object({
    name: t.String({
      error: "Name is required",
    }),
    age: t.Number(),
  }),
});

Error Code

Teasim error code consists of:

  • NOT_FOUND
  • INTERNAL_SERVER_ERROR
  • VALIDATION
  • PARSE
  • UNKNOWN

By default, user thrown error code is unknown.

TIP

If no error response is returned, the error will be returned using error.name.

Custom Error

Teasim supports custom error both in the type-level and implementation level.

Helping you to easily classify and narrow down the error type for full type safety with auto-complete:

class CustomError extends Error {
  constructor(public message: string) {
    super(message);
  }
}

new Teasim()
  .addError({
    MyError: CustomError,
  })
  .onError(({ code, error }) => {
    switch (code) {
      // With auto-completion
      case "MyError":
        // With type narrowing
        // Error is typed as CustomError
        return error;
    }
  })
  .get("/", () => {
    throw new CustomError("Hello Error");
  });

Catching all error

To list all errors, you can list an error using error.all.

new Teasim().post("/", ({ body }) => body, {
  body: t.Object({
    name: t.String(),
    age: t.Number(),
  }),
  error({ code, error }) {
    switch (code) {
      case "VALIDATION":
        console.log(error.all);

        // Find a specific error name (path is OpenAPI Schema compliance)
        const name = error.all.find(x => x.path === "/name");

        // If has validation error, then log it
        if (name) console.log(name);
    }
  },
});

With this you can overwrite provide an advance custom error message or monitor an error based on your need.

TIP

Make sure to narrow down Error code to "Validation" to narrow down error type before using error.all