/**
 * Shared explicit error types for relay-contracts.
 *
 * `coding-style.md`: "Never silently swallow errors" — every codec throws a typed,
 * descriptive error at the parse boundary instead of returning a partial/ambiguous value.
 */

/** Thrown when raw bytes / strings fail to decode into a frozen contract shape. */
export class ContractDecodeError extends Error {
  constructor(message: string) {
    super(message)
    this.name = 'ContractDecodeError'
  }
}

/** Thrown when a value violates a frozen contract invariant before encoding. */
export class ContractEncodeError extends Error {
  constructor(message: string) {
    super(message)
    this.name = 'ContractEncodeError'
  }
}

/**
 * Thrown by crypto-shaped functions whose *implementation* lives in another relay
 * package (P4 `relay-e2e/`, P5 `relay-auth/`). `relay-contracts` owns only the SHAPE
 * (signature + types) per PLAN_RELAY_INDEX §2.1; the runtime is provided downstream.
 */
export class NotImplementedInContractsError extends Error {
  constructor(fnName: string, owner: string) {
    super(
      `${fnName} is a frozen SIGNATURE only in relay-contracts; its crypto implementation lives in ${owner}. ` +
        `Import the implementation from that package — do not call it from relay-contracts.`,
    )
    this.name = 'NotImplementedInContractsError'
  }
}
