The Airdrop SDK provides pre-configured Axios HTTP clients with automatic retry logic and error handling for resilient network operations.
Pre-configured Axios instance with automatic retry capabilities.
/**
* Pre-configured Axios client with retry logic
* - 5 retries with exponential backoff
* - Retries on network errors, idempotent requests, and 5xx errors
* - Excludes 429 (rate limit) from automatic retries
* - Removes sensitive headers from error logs
*/
const axiosClient: AxiosInstance;Usage Examples:
import { axiosClient } from '@devrev/ts-adaas';
// GET request with automatic retries
const response = await axiosClient.get('https://api.example.com/data', {
params: { page: 1, limit: 100 },
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
// POST request with automatic retries
const createResponse = await axiosClient.post(
'https://api.example.com/items',
{
title: 'New Item',
description: 'Item description',
},
{
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
}
);
// PUT request (idempotent, will retry)
await axiosClient.put('https://api.example.com/items/123', {
title: 'Updated Title',
});
// DELETE request
await axiosClient.delete('https://api.example.com/items/123', {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});The original axios instance for custom configurations.
/**
* Original axios instance without retry configuration
* Use for custom configurations or when retries are not desired
*/
const axios: AxiosInstance;Usage Examples:
import { axios } from '@devrev/ts-adaas';
// Use original axios for custom configuration
const customClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {
'Custom-Header': 'value',
},
});
// Make request without retry logic
const response = await axios.get('https://api.example.com/data');The axiosClient is configured with the following retry behavior:
1 * 2^retryCount * 1000ms
import { axiosClient } from '@devrev/ts-adaas';
import { processTask, ExtractorEventType } from '@devrev/ts-adaas';
processTask({
task: async ({ adapter }) => {
try {
const response = await axiosClient.get('https://api.example.com/tasks', {
headers: {
Authorization: `Bearer ${adapter.event.payload.connection_data.key}`,
},
params: {
page: 1,
per_page: 100,
},
});
const tasks = response.data;
await adapter.getRepo('tasks')?.push(tasks);
await adapter.emit(ExtractorEventType.ExtractionDataDone);
} catch (error) {
console.error('Failed to fetch tasks:', error);
await adapter.emit(ExtractorEventType.ExtractionDataError, {
error: { message: `Failed to fetch tasks: ${error.message}` },
});
}
},
onTimeout: async ({ adapter }) => {
await adapter.emit(ExtractorEventType.ExtractionDataError, {
error: { message: 'Timeout' },
});
},
});processTask({
task: async ({ adapter }) => {
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await axiosClient.get('https://api.example.com/items', {
params: { page, per_page: 100 },
});
const items = response.data.items;
await adapter.getRepo('items')?.push(items);
hasMore = response.data.has_more;
page++;
}
await adapter.emit(ExtractorEventType.ExtractionDataDone);
},
onTimeout: async ({ adapter }) => {
await adapter.emit(ExtractorEventType.ExtractionDataError, {
error: { message: 'Timeout' },
});
},
});processTask({
task: async ({ adapter }) => {
try {
const response = await axiosClient.get('https://api.example.com/data');
await processData(response.data);
await adapter.emit(ExtractorEventType.ExtractionDataDone);
} catch (error) {
// Check for rate limiting (429 is not auto-retried)
if (error.response?.status === 429) {
const retryAfter = parseInt(error.response.headers['retry-after'] || '60');
// Emit delay event
await adapter.emit(ExtractorEventType.ExtractionDataDelay, {
delay: retryAfter,
});
} else {
await adapter.emit(ExtractorEventType.ExtractionDataError, {
error: { message: error.message },
});
}
}
},
onTimeout: async ({ adapter }) => {
await adapter.emit(ExtractorEventType.ExtractionDataError, {
error: { message: 'Timeout' },
});
},
});import { axiosClient } from '@devrev/ts-adaas';
import { processTask, LoaderEventType } from '@devrev/ts-adaas';
processTask({
task: async ({ adapter }) => {
const items = await getItemsToLoad();
for (const item of items) {
try {
const response = await axiosClient.post(
'https://api.example.com/items',
{
title: item.data.title,
description: item.data.description,
},
{
headers: {
Authorization: `Bearer ${adapter.event.payload.connection_data.key}`,
'Content-Type': 'application/json',
},
}
);
const externalId = response.data.id;
// Create mapping
await adapter.mappers.create({
sync_unit: adapter.event.payload.event_context.sync_unit,
external_ids: [externalId],
targets: [item.id.devrev],
status: 'operational',
});
} catch (error) {
console.error(`Failed to create item ${item.id.devrev}:`, error);
}
}
await adapter.emit(LoaderEventType.DataLoadingDone);
},
onTimeout: async ({ adapter }) => {
await adapter.emit(LoaderEventType.DataLoadingError, {
error: { message: 'Timeout' },
});
},
});import { axios } from '@devrev/ts-adaas';
import axiosRetry from 'axios-retry';
// Create custom client with different retry configuration
const customClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// Configure custom retry logic
axiosRetry(customClient, {
retries: 3,
retryDelay: (retryCount) => retryCount * 2000, // Linear backoff
retryCondition: (error) => {
return error.response?.status === 503; // Only retry on 503
},
});
// Use custom client
const response = await customClient.get('/data');processTask({
task: async ({ adapter }) => {
const attachments = await getAttachmentsToExtract();
for (const attachment of attachments) {
try {
// Stream attachment download
const response = await axiosClient.get(attachment.url, {
responseType: 'stream',
});
// Process stream
await processAttachmentStream(response.data);
} catch (error) {
console.error(`Failed to download attachment ${attachment.id}:`, error);
}
}
await adapter.emit(ExtractorEventType.ExtractionAttachmentsDone);
},
onTimeout: async ({ adapter }) => {
await adapter.emit(ExtractorEventType.ExtractionAttachmentsError, {
error: { message: 'Timeout' },
});
},
});const apiKey = adapter.event.payload.connection_data.key;
const response = await axiosClient.get('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});try {
const response = await axiosClient.get('https://api.example.com/data');
return response.data;
} catch (error) {
if (error.response) {
// Server responded with error status
console.error('Server error:', error.response.status, error.response.data);
} else if (error.request) {
// Request made but no response received
console.error('Network error:', error.message);
} else {
// Error setting up request
console.error('Request error:', error.message);
}
throw error;
}// GET for retrieval (idempotent, will retry)
await axiosClient.get('/items/123');
// POST for creation (not idempotent, won't retry by default)
await axiosClient.post('/items', data);
// PUT for full updates (idempotent, will retry)
await axiosClient.put('/items/123', data);
// PATCH for partial updates (not idempotent, won't retry by default)
await axiosClient.patch('/items/123', partialData);
// DELETE for removal (idempotent, will retry)
await axiosClient.delete('/items/123');// Set per-request timeout
await axiosClient.get('https://api.example.com/data', {
timeout: 30000, // 30 seconds
});
// Create client with default timeout
const client = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000, // 10 seconds default
});