update
This commit is contained in:
@@ -162,8 +162,6 @@ tap.test('should create and download PDF statement', async () => {
|
||||
});
|
||||
|
||||
tap.test('should create CSV statement with custom date range', async () => {
|
||||
// Wait to avoid rate limiting
|
||||
await new Promise(resolve => setTimeout(resolve, 3500));
|
||||
console.log('Creating CSV statement export...');
|
||||
|
||||
// Use last month's date range to ensure it's in the past
|
||||
@@ -200,8 +198,6 @@ tap.test('should create CSV statement with custom date range', async () => {
|
||||
});
|
||||
|
||||
tap.test('should create MT940 statement', async () => {
|
||||
// Wait to avoid rate limiting
|
||||
await new Promise(resolve => setTimeout(resolve, 3500));
|
||||
console.log('Creating MT940 statement export...');
|
||||
|
||||
const exportBuilder = primaryAccount.getAccountStatement({
|
||||
|
@@ -24,9 +24,46 @@ export class BunqHttpClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an API request to bunq
|
||||
* Make an API request to bunq with automatic retry on rate limit
|
||||
*/
|
||||
public async request<T = any>(options: IBunqRequestOptions): Promise<T> {
|
||||
const maxRetries = 3;
|
||||
let lastError: Error;
|
||||
|
||||
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
return await this.makeRequest<T>(options);
|
||||
} catch (error) {
|
||||
lastError = error as Error;
|
||||
|
||||
// Check if it's a rate limit error
|
||||
if (error instanceof BunqApiError) {
|
||||
const isRateLimitError = error.errors.some(e =>
|
||||
e.error_description.includes('Too many requests') ||
|
||||
e.error_description.includes('rate limit')
|
||||
);
|
||||
|
||||
if (isRateLimitError && attempt < maxRetries) {
|
||||
// Exponential backoff: 1s, 2s, 4s
|
||||
const backoffMs = Math.pow(2, attempt) * 1000;
|
||||
console.log(`Rate limit hit, backing off for ${backoffMs}ms (attempt ${attempt + 1}/${maxRetries + 1})`);
|
||||
await new Promise(resolve => setTimeout(resolve, backoffMs));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// For non-rate-limit errors or if we've exhausted retries, throw immediately
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to make the actual request
|
||||
*/
|
||||
private async makeRequest<T = any>(options: IBunqRequestOptions): Promise<T> {
|
||||
let url = `${this.context.baseUrl}${options.endpoint}`;
|
||||
|
||||
// Prepare headers
|
||||
|
Reference in New Issue
Block a user