Skip to content
i18n-error-base
English
Esc
↑↓navigate↵open⌘Jpreview
On this page

Usage

Basic operations for defining error classes, registering messages, switching languages, prefixes, and fallback.

Basic flow

Define an error class

Extend I18nErrorBase<TMeta> and define info for message generation in TMeta.

Register per-language messages

Register the message for each class and language with setErrorMessage.

Switch languages and read message

Switch with setGlobalConfig({ lang }) and read error.message.

import { setGlobalConfig } from "valibot";
import { I18nErrorBase, setErrorMessage } from "i18n-error-base";

class BusinessRuleError extends I18nErrorBase<{ code: string; limit: number }> {
  public constructor(meta: { code: string; limit: number }) {
    super(meta, ({ code, limit }) => `Code: ${code}, Limit: ${limit}`);
  }
}

setErrorMessage(
  BusinessRuleError,
  ({ code, limit }) => `コード: ${code}、制限: ${limit}`,
  "ja",
);

const error = new BusinessRuleError({ code: "ERR", limit: 50 });

setGlobalConfig({ lang: "ja" });
console.log(error.message); // コード: ERR、制限: 50

setGlobalConfig({ lang: "en" });
console.log(error.message); // Code: ERR, Limit: 50

Define an error class

TMeta is auxiliary info for message generation. It is kept in error.meta and passed to registered functions.

import { I18nErrorBase } from "i18n-error-base";

class NotFoundError extends I18nErrorBase<{ resource: string }> {}

const error = new NotFoundError({ resource: "user" }, "fallback message");
console.log(error.meta); // { resource: "user" }

The second argument is a string or a (meta) => string function. The third is { cause } and other Error options.

class TestError extends I18nErrorBase<{ code: string }> {}

const cause = new Error("original");
const error = new TestError({ code: "ERR" }, "something went wrong", { cause });
console.log(error.cause === cause); // true

Setting TMeta to undefined lets you omit meta.

class NoMetaError extends I18nErrorBase<undefined> {}

const a = new NoMetaError("no meta");
const b = new NoMetaError(undefined, "no meta");
console.log(a.meta); // undefined

Register messages

setErrorMessage registers per-class, per-language factory functions.

import { I18nErrorBase, setErrorMessage } from "i18n-error-base";

class TestError extends I18nErrorBase<{ code: string }> {}

setErrorMessage(TestError, ({ code }) => `エラーコード: ${code}`, "ja");
setErrorMessage(TestError, "something went wrong", "en");

Strings are also allowed. Languages can be specified as arrays.

const message = ({ code }: { code: string }) => `エラーコード: ${code}`;
setErrorMessage(TestError, message, ["ja", "ko", "zh"]);

Re-registering the same class and language overwrites. It applies only when the constructors at registration and lookup match, not via instanceof.

Switch languages

Switch with Valibot’s global config. message refers to the current lang on each read.

import { setGlobalConfig } from "valibot";

setGlobalConfig({ lang: "ja" });
console.log(error.message); // 日本語の登録メッセージ

setGlobalConfig({ lang: "en" });
console.log(error.message); // 英語の登録メッセージ or 既定メッセージ

Unset lang is "en". Unregistered languages use the constructor’s default message.

setErrorMessage(BusinessRuleError, () => "日本語メッセージ", "ja");

setGlobalConfig({ lang: "fr" });
console.log(error.message); // "Code: ERR, Limit: 50"(既定メッセージ)

Add a prefix

static prefix is prepended to the resolved message. It applies to both translated and default messages.

class PrefixedError extends I18nErrorBase<{ code: string }> {
  static {
    this.prefix = "[ERROR] ";
  }
}

setErrorMessage(PrefixedError, ({ code }) => `code is ${code}`, "ja");
const error = new PrefixedError({ code: "ERR" }, "fallback");

setGlobalConfig({ lang: "ja" });
console.log(error.message); // "[ERROR] code is ERR"

setGlobalConfig({ lang: "en" });
console.log(error.message); // "[ERROR] fallback"

When unset, it is returned as is.

Behavior as an Error

  • error instanceof Error, instanceof I18nErrorBase, and instanceof <concrete class> are all true
  • String(error) / error.toString() include the resolved message (e.g. "Error: ...")
  • cause is kept via { cause }

Common patterns

Fix the default message in the constructor

class BusinessRuleError extends I18nErrorBase<{ code: string; limit: number }> {
  public constructor(meta: { code: string; limit: number }, options?: ErrorOptions) {
    super(meta, ({ code, limit }) => `Code: ${code}, Limit: ${limit}`, options);
  }
}

Callers only pass meta, avoiding duplication of the default text.

Register multiple languages at once

setErrorMessage(MyError, "エラーが発生しました", ["ja"]);
setErrorMessage(MyError, "An error occurred", ["en", "en-US"]);

Language codes are not normalized. "en" and "en-US" are separate keys, so register needed codes explicitly.

Was this page helpful?