generated from coulomb/repo-seed
Add Binect SDK implementation, Explorer, and test suite
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>
This commit is contained in:
71
src/errors.ts
Normal file
71
src/errors.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
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';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user