コンテンツにスキップ
UniKVS
Esc
↑↓移動↵開く⌘Jプレビュー
このページの内容

エラー

@unikvs/core のエラー基盤。ErrorBase・setErrorMessage・言語切り替えと 6 種類の共通エラーの使い方を説明します。

概要

@unikvs/core のエラーは i18n-error-base の仕組みを使っています。すべての共通エラーは ErrorBase から派生し、meta に対応する値を保持します。メッセージは既定の英語に加えて、日本語 (ja) が登録済みです。

共通エラーは次の 6 種類です。

エラークラス 継承 name 詳しい説明
KeyNotFoundError ErrorBase UniKvsKeyNotFoundError 詳細
UnsupportedRuntimeError InvalidUsageErrorBase UniKvsUnsupportedRuntimeError 詳細
InvalidPartSizeError ErrorBase UniKvsInvalidPartSizeError 詳細
StorageAbortedError ErrorBase UniKvsStorageAbortedError 詳細
RepairNotAllowedError ErrorBase UniKvsRepairNotAllowedError 詳細
ReadonlyVariableError InvalidUsageErrorBase UniKvsReadonlyVariableError 詳細

InvalidUsageErrorBase を継承する 2 種類 (UnsupportedRuntimeError・ReadonlyVariableError) は呼び出し側の修正が必要です。それ以外は実行時の状態 (キーの有無、中断、設定値、権限) に応じて対処します。

エラー基盤

型・値 説明
ErrorMeta Readonly<Record<string, unknown>>。meta の形状
ErrorOptions cause を保持できるオプション ({ cause?: unknown })
ErrorBase<TMeta> 基底クラス。meta とメッセージ生成関数を受け取る
InvalidUsageErrorBase<TMeta> 使い方の誤り用。ErrorBase を継承
setErrorMessage クラスと言語ごとのメッセージを登録する

コンストラクター

ErrorBase は meta とメッセージ (文字列または生成関数) を受け取ります。meta が undefined の型では、メッセージのみの形式も使えます。

import { ErrorBase } from "@unikvs/core";

// meta あり: 参照をそのまま保持します
const error = new ErrorBase({ key: "foo" }, ({ key }) => `Key not found: ${key}`);

console.log(error.meta); // { key: "foo" }
console.log(error.message); // "Key not found: foo"
console.log(error.toString()); // "Error: Key not found: foo" (name 未設定時)

// meta なし
const plain = new ErrorBase(undefined, "boom");
console.log(plain.meta); // undefined

name と prefix

name はプロトタイプに設定します。設定しなければ Error を継承した名前 ("Error") になります。共通エラーはすべて UniKvs*Error 形式の名前を持ちます。

class KeyNotFoundError extends ErrorBase<{ readonly key: string }> {
  static {
    this.prototype.name = "KeyNotFoundError";
  }
}

prefix を設定すると、翻訳後のメッセージを含めた全体の先頭に付加されます。

class PrefixedError extends ErrorBase<{ readonly key: string }> {
  static {
    this.prototype.name = "PrefixedError";
  }

  public constructor(args: { readonly key: string }) {
    super(args, ({ key }) => `Missing: ${key}`);
  }
}

PrefixedError.prefix = "[test] ";
console.log(new PrefixedError({ key: "foo" }).message); // "[test] Missing: foo"

cause

cause の扱いは標準の Error と同じです。options を省略すると cause プロパティー自体が存在せず、明示的に渡すと参照をそのまま保持します。Error 以外の値も渡せます。

const withCause = new KeyNotFoundError({ key: "foo" }, { cause: { reason: "disk full" } });
console.log("cause" in withCause); // true

const withoutOptions = new KeyNotFoundError({ key: "foo" });
console.log("cause" in withoutOptions); // false

言語切り替え

メッセージの言語は Valibot のグローバル設定で切り替えます。valibot はピア依存のため、使う側でインストールします。

import { deleteGlobalConfig, setGlobalConfig } from "valibot";
import { KeyNotFoundError } from "@unikvs/core";

console.log(new KeyNotFoundError({ key: "k1" }).message);
// "Key not found: k1"

setGlobalConfig({ lang: "ja" });
console.log(new KeyNotFoundError({ key: "k1" }).message);
// "キー k1 が見つかりません"

deleteGlobalConfig(); // 既定の英語に戻る

共通エラーには英語の既定メッセージと日本語のメッセージが登録済みです。未登録の言語では既定の英語メッセージが使われます。

メッセージの登録

自作エラーにも setErrorMessage で言語ごとのメッセージを登録できます。文字列または meta を受け取る関数を、言語タグ (単体または Set などの反復可能オブジェクト) とともに渡します。

import { ErrorBase, setErrorMessage } from "@unikvs/core";

class MyError extends ErrorBase<{ readonly key: string }> {
  static {
    this.prototype.name = "MyError";
  }

  public constructor(args: { readonly key: string }) {
    super(args, ({ key }) => `Missing: ${key}`);
  }
}

setErrorMessage(MyError, ({ key }) => `キー ${key} がありません`, "ja");
setErrorMessage(MyError, "not found", new Set(["ja", "fr"])); // 複数言語へ一括登録も可能

登録には次の規則があります。

  • クラス単位で解決され、親クラスへの登録は子クラスへ継承されません。
  • 同じ言語へ再登録すると新しいメッセージで上書きされます。
  • 空文字列を登録してもフォールバックしません。空文字列がそのままメッセージになります。
  • 登録したメッセージ関数は meta を参照として受け取ります。
  • I18nErrorBase を継承していないクラスへは登録できません。

共通エラー

6 種類の具体的なエラーはいずれも meta に対応する値を保持します。instanceof で判別し、meta から復旧に必要な情報を取り出します。

import { KeyNotFoundError } from "@unikvs/core";

try {
  throw new KeyNotFoundError({ key: "missing-key" });
} catch (ex) {
  if (ex instanceof KeyNotFoundError) {
    console.log(ex.meta); // { key: "missing-key" }
    console.log(ex.message); // "Key not found: missing-key"
  } else {
    throw ex;
  }
}

KeyNotFoundError

どのストレージにもキーがないときに使います。get の失敗時に投げられます。

プロパティ型
keystring

見つからなかったキーです。

型string
  • 継承: ErrorBase
  • name: UniKvsKeyNotFoundError
  • 英語: Key not found: k1
  • 日本語: キー k1 が見つかりません

UnsupportedRuntimeError

対応ランタイム外でプラグインを使ったときに使います。使い方の誤りのため InvalidUsageErrorBase を継承します。

プロパティ型
namestring

プラグインの表示名です。

型string
runtimestring

対応するランタイム名です。

型string
throw new UnsupportedRuntimeError({ name: "Redis", runtime: "Bun" });
// "Redis can only be used in the Bun runtime"
// (ja) "Redis は Bun ランタイムでのみ使用できます"
  • 継承: InvalidUsageErrorBase
  • name: UniKvsUnsupportedRuntimeError

InvalidPartSizeError

vars のパートサイズが非整数または非正数のときに使います。actual に指定値をそのまま保持します。

プロパティ型
actualunknown

指定されたパートサイズの値です。

型unknown
throw new InvalidPartSizeError({ actual: 0 });
// "Invalid part size 0 was specified in the vars. ... Specify a positive integer in bytes such as 5242880."
// (ja) "変数に無効なパートサイズ 0 が指定されました。..."
  • 継承: ErrorBase
  • name: UniKvsInvalidPartSizeError

StorageAbortedError

渡された AbortSignal が既に中断済みのため、書き込みストリームの取得前に拒否されたときに使います。開始前に中断が確定している要求は成功しないため、即座に失敗させます。

プロパティ型
keystring

アップロードしようとしたキーです。

型string
  • 継承: ErrorBase
  • name: UniKvsStorageAbortedError
  • 英語: "k1" を含む中断理由の説明 (The upload for key "k1" was aborted before it started ...)
  • 日本語: "k1" を含む同様の説明

対処は中断されていないシグナルを渡すか、要求前にシグナルの状態を確認します。

RepairNotAllowedError

repair: true の読み取りで、前段ストレージへの書き戻しが拒否されたときに使います。names は書き戻し先の表示名で、凍結された配列として保持されます。

プロパティ型
namesreadonly string[]

書き戻し先の表示名の一覧です。

型readonly string[]
new RepairNotAllowedError({ names: ["Memory"] }).message;
// 'Repair writes via "Memory" are not allowed'
// (ja) '"Memory" への書き戻しは許可されていません'

new RepairNotAllowedError({ names: [] }).message;
// 'Repair writes via "(unknown)" are not allowed' (空配列は不明名で組み立て)
  • 継承: ErrorBase
  • name: UniKvsRepairNotAllowedError

書き戻しの可否は @unikvs/allow-repair で制御し、拒否時の meta.names に書き戻し先の表示名が入ります。

ReadonlyVariableError

setReadonly() で固定された変数への書き込みがあったときに使います。使い方の誤りのため InvalidUsageErrorBase を継承します。

プロパティ型
namestring

変更しようとした変数名です。

型string
new ReadonlyVariableError({ name: "x" }).message;
// 'Cannot modify readonly variable: "x"'
// (ja) '読み取り専用の変数 "x" は変更できません'
  • 継承: InvalidUsageErrorBase
  • name: UniKvsReadonlyVariableError

詳しくはパイプラインコンテキスト › 変数の読み書きを参照してください。

このページは役に立ちましたか?