Skip to content
markpaper

src/account/errors.ts

v0.3.0 · 1.7 KB

Download file
/**
 * Error codes raised by the account module.
 *
 * - `DEGRADED_PERP` — a `clearinghouseState` answer failed validation (for example HTTP 200 without
 *   `marginSummary`). It is a broken read, never an empty account: skip the tick, keep last-known-good.
 * - `INVALID_RESPONSE` — an info answer has an unexpected shape.
 * - `INVALID_ARGUMENT` — a caller-supplied value is malformed (address, dex list, options).
 * - `MISSING_MAIN_DEX` — a snapshot without the main perp dex (`""`) cannot produce equity.
 * - `ADDRESS_IS_AGENT` — the "account" address is an API wallet; it holds no positions.
 * - `UNKNOWN_ADDRESS` — `userRole` says `missing`: the exchange has never seen this address.
 * - `MASTER_MISMATCH` — configured master disagrees with the exchange, or master equals the account.
 * - `MASTER_UNKNOWN` — a sub-account/vault whose master could not be determined.
 */
export type HlAccountErrorCode =
  | 'DEGRADED_PERP'
  | 'INVALID_RESPONSE'
  | 'INVALID_ARGUMENT'
  | 'MISSING_MAIN_DEX'
  | 'ADDRESS_IS_AGENT'
  | 'UNKNOWN_ADDRESS'
  | 'MASTER_MISMATCH'
  | 'MASTER_UNKNOWN';

export class HlAccountError extends Error {
  readonly code: HlAccountErrorCode;
  /** Perp dex the error refers to (`""` = main dex), when applicable. */
  readonly dex: string | undefined;

  constructor(code: HlAccountErrorCode, message: string, details: { dex?: string; cause?: unknown } = {}) {
    super(message, details.cause === undefined ? undefined : { cause: details.cause });
    this.name = 'HlAccountError';
    this.code = code;
    this.dex = details.dex;
  }
}

/** Human label for a dex id; the main dex is the empty string. */
export function dexLabel(dex: string): string {
  return dex === '' ? 'main dex' : `dex "${dex}"`;
}
All files