binect-js/src/errors.ts

72 lines
2 KiB
TypeScript
Raw Normal View History

import type { ApiErrorResponse } from './types.js';
/**
* Error thrown when the Binect API returns a non-success response.
* Preserves HTTP status, endpoint, and parsed response body.
*/
export class BinectApiError extends Error {
/** HTTP status code */
public readonly status: number;
/** API endpoint that was called */
public readonly endpoint: string;
/** HTTP method used */
public readonly method: string;
/** Parsed error response from API (when available) */
public readonly response: ApiErrorResponse | null;
constructor(
message: string,
status: number,
endpoint: string,
method: string,
response: ApiErrorResponse | null = null
) {
super(message);
this.name = 'BinectApiError';
this.status = status;
this.endpoint = endpoint;
this.method = method;
this.response = response;
// Maintains proper stack trace for where error was thrown (V8 engines)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, BinectApiError);
}
}
/**
* Returns a detailed string representation of the error
*/
toDetailedString(): string {
const parts = [
`BinectApiError: ${this.message}`,
` Status: ${this.status}`,
` Endpoint: ${this.method} ${this.endpoint}`,
];
if (this.response) {
if (this.response.error) {
parts.push(` Error: ${this.response.error}`);
}
if (this.response.message) {
parts.push(` Message: ${this.response.message}`);
}
if (this.response.details && this.response.details.length > 0) {
parts.push(` Details: ${this.response.details.join(', ')}`);
}
}
return parts.join('\n');
}
}
/**
* Error thrown when credentials are invalid or missing
*/
export class BinectAuthError extends BinectApiError {
constructor(endpoint: string, method: string, response: ApiErrorResponse | null = null) {
super('Authentication failed: Invalid credentials', 401, endpoint, method, response);
this.name = 'BinectAuthError';
}
}