Comprehensive error handling system for Ledger hardware wallet applications and libraries
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Error classes for network connectivity, API communication, and external service integration issues.
interface APIConfig {
baseURL: string;
apiKey?: string;
timeout?: number;
headers?: Record<string, string>;
}Errors related to network connectivity and connection failures.
const NetworkDown: CustomErrorFunc;
const WebsocketConnectionError: CustomErrorFunc;
const WebsocketConnectionFailed: CustomErrorFunc;Usage Examples:
import {
NetworkDown,
WebsocketConnectionError,
WebsocketConnectionFailed
} from "@ledgerhq/errors";
// Handle network connectivity issues
try {
await fetchAccountData();
} catch (error) {
if (error instanceof NetworkDown) {
console.log("Network is unavailable - please check your connection");
showOfflineMode();
}
}
// Handle websocket connection errors
try {
await connectWebSocket();
} catch (error) {
if (error instanceof WebsocketConnectionError) {
console.log("WebSocket connection error - retrying...");
retryConnection();
} else if (error instanceof WebsocketConnectionFailed) {
console.log("WebSocket connection failed - falling back to HTTP");
useHttpFallback();
}
}
// Example with retry logic
async function establishWebSocketConnection(maxRetries: number = 3): Promise<WebSocket> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await connectWebSocket();
} catch (error) {
if (error instanceof WebsocketConnectionFailed && attempt < maxRetries) {
console.log(`WebSocket attempt ${attempt} failed, retrying...`);
await delay(1000 * attempt); // Exponential backoff
continue;
}
throw error;
}
}
throw new WebsocketConnectionFailed("Max connection attempts exceeded");
}Errors specific to Ledger's API services and backend communication.
const LedgerAPIError: CustomErrorFunc;
const LedgerAPIErrorWithMessage: CustomErrorFunc;
const LedgerAPINotAvailable: CustomErrorFunc;
const LedgerAPI4xx: CustomErrorFunc;
const LedgerAPI5xx: CustomErrorFunc;Usage Examples:
import {
LedgerAPIError,
LedgerAPIErrorWithMessage,
LedgerAPINotAvailable,
LedgerAPI4xx,
LedgerAPI5xx
} from "@ledgerhq/errors";
// Handle general API errors
try {
await callLedgerAPI("/accounts");
} catch (error) {
if (error instanceof LedgerAPIError) {
console.log("Ledger API request failed");
}
}
// Handle API errors with specific messages
try {
const response = await fetch("/api/transactions");
if (!response.ok) {
const errorData = await response.json();
throw new LedgerAPIErrorWithMessage(errorData.message || "API request failed");
}
} catch (error) {
if (error instanceof LedgerAPIErrorWithMessage) {
showUserMessage(error.message);
}
}
// Handle API availability
async function checkAPIStatus() {
try {
await fetch("/api/health");
} catch (error) {
throw new LedgerAPINotAvailable("Ledger API services are currently unavailable");
}
}
// Handle HTTP status code errors
async function handleAPIResponse(response: Response) {
if (response.status >= 400 && response.status < 500) {
throw new LedgerAPI4xx(`Client error: ${response.status} ${response.statusText}`);
} else if (response.status >= 500) {
throw new LedgerAPI5xx(`Server error: ${response.status} ${response.statusText}`);
}
return response;
}
// Example API client with comprehensive error handling
class LedgerAPIClient {
async request(endpoint: string, options: RequestInit = {}) {
try {
const response = await fetch(`https://api.ledger.com${endpoint}`, options);
if (response.status >= 500) {
throw new LedgerAPI5xx(`Server error: ${response.status}`);
} else if (response.status >= 400) {
const errorData = await response.json().catch(() => ({}));
throw new LedgerAPI4xx(errorData.message || `Client error: ${response.status}`);
}
return response.json();
} catch (error) {
if (error instanceof TypeError && error.message.includes("fetch")) {
throw new LedgerAPINotAvailable("Unable to connect to Ledger API");
}
throw error;
}
}
async getAccount(accountId: string) {
try {
return await this.request(`/accounts/${accountId}`);
} catch (error) {
if (error instanceof LedgerAPI4xx) {
console.log("Account not found or access denied");
} else if (error instanceof LedgerAPI5xx) {
console.log("Server error - please try again later");
}
throw error;
}
}
}Errors related to API endpoint configuration and connectivity.
const EnpointConfigError: CustomErrorFunc;Usage Examples:
import { EnpointConfigError } from "@ledgerhq/errors";
// Validate endpoint configuration
function validateEndpointConfig(config: APIConfig) {
if (!config.baseURL || !config.apiKey) {
throw new EnpointConfigError("API endpoint configuration is incomplete");
}
try {
new URL(config.baseURL);
} catch {
throw new EnpointConfigError("Invalid API endpoint URL format");
}
}
// Handle configuration errors in API client
class APIClient {
constructor(config: APIConfig) {
try {
validateEndpointConfig(config);
this.config = config;
} catch (error) {
if (error instanceof EnpointConfigError) {
console.error("API client initialization failed:", error.message);
}
throw error;
}
}
async makeRequest(path: string) {
if (!this.config.baseURL) {
throw new EnpointConfigError("API endpoint not configured");
}
// Make request...
}
}
// Example usage
try {
const client = new APIClient({
baseURL: process.env.API_URL,
apiKey: process.env.API_KEY
});
} catch (error) {
if (error instanceof EnpointConfigError) {
console.log("Please check your API configuration");
}
}