generated from coulomb/repo-seed
SDK (@binect/js): - BinectClient with domain sub-clients (documents, sendings, accounts, attachments, invoices) - HTTP Basic Auth, native fetch only (no runtime dependencies) - TypeScript types matching Binect API vocabulary - Status predicates and polling helpers in helpers.ts - Structured error handling (BinectApiError, BinectAuthError) Explorer: - Standalone browser-based API explorer (explorer/index.html) - Interactive testing without code Tests: - Unit tests for client, types, errors, helpers, http - E2E tests for upload/delete and send/cancel workflows Also includes: - Architecture Decision Records (ADRs) - Example DIN 5008 letter PDFs for testing - API specification research notes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
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';
|
|
}
|
|
}
|