// Author: fruit.com.cn export class ApiError extends Error { constructor(message, { status = 0, code = null, path = '', cause } = {}) { super(message); this.name = 'ApiError'; this.status = status; this.code = code; this.path = path; this.cause = cause; } } export class TimeoutError extends ApiError { constructor(path, timeout) { super(`Request timed out after ${timeout}ms`, { path }); this.name = 'TimeoutError'; } } export class NetworkError extends ApiError { constructor(path, cause) { super('Network request failed', { path, cause }); this.name = 'NetworkError'; } } export class CanceledError extends ApiError { constructor(path) { super('Request canceled', { path }); this.name = 'CanceledError'; } } export function isCanceled(error) { return error instanceof CanceledError || error?.name === 'CanceledError' || error?.name === 'AbortError'; }