The SDK provides typed error classes for different error scenarios, making it easy to handle specific error cases in your application.
All error classes extend ArubaApiError, which extends the native Error class.
Base error class for all API errors.
class ArubaApiError extends Error {
readonly code: string; // Error code
readonly statusCode: number; // HTTP status code
readonly details?: string; // Additional details
}
Example:
import { ArubaApiError } from '@fatturazione-elettronica-aruba/core';
try {
await invoices.upload({ dataFile });
} catch (error) {
if (error instanceof ArubaApiError) {
console.log(`Error [${error.code}]: ${error.message}`);
console.log(`HTTP Status: ${error.statusCode}`);
if (error.details) {
console.log(`Details: ${error.details}`);
}
}
}
Thrown when authentication fails (401 Unauthorized).
class AuthenticationError extends ArubaApiError {
// code: 'AUTH_ERROR'
// statusCode: 401
}
Common causes:
Example:
import { AuthenticationError } from '@fatturazione-elettronica-aruba/core';
try {
await client.auth.signIn(username, password);
} catch (error) {
if (error instanceof AuthenticationError) {
console.log('Invalid credentials or session expired');
}
}
Thrown when rate limits are exceeded (429 Too Many Requests).
class RateLimitError extends ArubaApiError {
readonly retryAfter?: number; // Seconds to wait before retry
// code: 'RATE_LIMIT'
// statusCode: 429
}
Rate limits:
| Endpoint | Limit |
|---|---|
| Authentication | 1 request/minute |
| Invoice upload | 30 requests/minute |
| Search | 12 requests/minute |
Example:
import { RateLimitError } from '@fatturazione-elettronica-aruba/core';
try {
await invoices.upload({ dataFile });
} catch (error) {
if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
await sleep(error.retryAfter * 1000);
// Retry the request
}
}
Thrown when a request times out.
class TimeoutError extends ArubaApiError {
// code: 'TIMEOUT'
// statusCode: 408
}
Example:
import { TimeoutError } from '@fatturazione-elettronica-aruba/core';
try {
await invoices.findSent({ creationStartDate, creationEndDate });
} catch (error) {
if (error instanceof TimeoutError) {
console.log('Request timed out, please try again');
}
}
Thrown when a network error occurs (connection failed, DNS error, etc.).
class NetworkError extends ArubaApiError {
// code: 'NETWORK_ERROR'
// statusCode: 0
}
Example:
import { NetworkError } from '@fatturazione-elettronica-aruba/core';
try {
await client.auth.signIn(username, password);
} catch (error) {
if (error instanceof NetworkError) {
console.log('Network error - check your internet connection');
}
}
| Status | Description | SDK Behavior |
|---|---|---|
400 | Bad Request | Throws ArubaApiError with validation details |
401 | Unauthorized | Attempts token refresh, then throws AuthenticationError |
403 | Forbidden | Throws ArubaApiError (missing permissions) |
404 | Not Found | Throws ArubaApiError (resource not found) |
413 | Payload Too Large | Throws ArubaApiError (file > 5MB) |
429 | Too Many Requests | Auto-retry with exponential backoff, then throws RateLimitError |
500 | Server Error | Automatic retry, then throws ArubaApiError |
Returned immediately by the API during upload operations:
| Code | Description | Action |
|---|---|---|
0000 | Operation completed | Success |
0001 | Filename already exists | Use a different filename |
0002 | Duplicate invoice | Invoice already sent |
0003 | Space limit exceeded | Contact Aruba for more space |
0004 | Invalid file | Check XML format |
0005 | Invalid Base64 content | Re-encode the file |
0006 | Invalid document type | Check TipoDocumento |
0007 | Invalid signature | Re-sign the invoice |
0008 | Certificate expired | Renew certificate |
0009 | Certificate revoked | Use valid certificate |
0010 | Untrusted certificate | Use Aruba-approved CA |
0096 | Service unavailable | Retry later |
0097 | Internal error | Contact support |
0098 | Timeout | Retry the request |
0099 | Generic error | Check request format |
Received via NS (Notifica di Scarto) notification from SDI:
| Code | Description | Action |
|---|---|---|
FATRSM200 | File format non-compliant | Validate XML against FatturaPA schema |
FATRSM201 | Invalid transmission ID | Check progressivoInvio format |
FATRSM212 | IdTrasmittente differs from Aruba's | Use Aruba's ID (01879020517) |
FATRSM213 | Invalid recipient code | Verify codiceDestinatario |
FATRSM214 | Invalid recipient PEC | Verify PEC address |
FATRSM215 | Unsupported transmission format | Use FPR12 or FPA12 |
import {
ArubaApiError,
AuthenticationError,
RateLimitError,
TimeoutError,
NetworkError,
} from '@fatturazione-elettronica-aruba/core';
async function uploadInvoiceSafely(invoices: InvoicesClient, dataFile: string) {
try {
const result = await invoices.upload({ dataFile });
return { success: true, data: result };
} catch (error) {
if (error instanceof AuthenticationError) {
// Session expired - re-authenticate
return { success: false, error: 'AUTH_EXPIRED', message: 'Please login again' };
}
if (error instanceof RateLimitError) {
// Rate limited - wait and retry
return {
success: false,
error: 'RATE_LIMITED',
retryAfter: error.retryAfter,
message: `Too many requests. Retry after ${error.retryAfter}s`,
};
}
if (error instanceof TimeoutError) {
// Timeout - can retry
return { success: false, error: 'TIMEOUT', message: 'Request timed out' };
}
if (error instanceof NetworkError) {
// Network issue - check connection
return { success: false, error: 'NETWORK', message: 'Network error' };
}
if (error instanceof ArubaApiError) {
// API error with code
return {
success: false,
error: error.code,
message: error.message,
details: error.details,
};
}
// Unknown error
throw error;
}
}
You can use instanceof to check error types:
function isRetryable(error: unknown): boolean {
if (error instanceof RateLimitError) return true;
if (error instanceof TimeoutError) return true;
if (error instanceof NetworkError) return true;
if (error instanceof ArubaApiError && error.statusCode >= 500) return true;
return false;
}