Open1

TypeScriptで判別可能なエラー型を定義する

Nakano as a ServiceNakano as a Service
import type { Result, ResultAsync } from 'neverthrow';
import { err, errAsync } from 'neverthrow';

interface PubErrProps<C extends string, E = undefined> {
  /**
   * エラーを一意に識別するエラーコード。ユーザーにも公開する。
   */
  code: C;
  /**
   * ユーザーに表示するエラーメッセージ。
   */
  message: string;
  /**
   * エラーの原因となるオブジェクト。不用意にユーザーに公開してはならない。
   */
  cause?: E;
}

export class PubErr<C extends string, E = undefined> extends Error {
  code: C;
  cause: E;

  constructor({ code, message, cause }: PubErrProps<C, E>) {
    super(message);
    this.name = `PubErr(${code})`;
    this.code = code;
    this.cause = cause as E;
  }
}

export function pubErr<C extends string, T = never, E = never>(
  content: PubErrProps<C, E>,
): Result<T, PubErr<C, E>> {
  return err(new PubErr(content));
}

export function pubErrAsync<C extends string, T = never, E = never>(
  content: PubErrProps<C, E>,
): ResultAsync<T, PubErr<C, E>> {
  return errAsync(new PubErr(content));
}

export function truncatePubErr<C extends string>(err: PubErr<C, unknown>) {
  return {
    code: err.code,
    message: err.message,
  };
}