Skip to content

Commit 0a7dc8d

Browse files
Merge pull request #129 from contentstack/staging
Release PR
2 parents 4b7cde6 + 76898c3 commit 0a7dc8d

File tree

8 files changed

+655
-629
lines changed

8 files changed

+655
-629
lines changed

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fileignoreconfig:
33
ignore_detectors:
44
- filecontent
55
- filename: package-lock.json
6-
checksum: 34d28e7736ffac2b27d3708b6bca28591f3a930292433001d2397bfdf2d2fd0f
6+
checksum: 52799bf1f9a1c387a74baeecac6c1c08f22bb8abdd2a1f0e689d8ed374b47635
77
- filename: .husky/pre-commit
88
checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193
99
- filename: test/request.spec.ts

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
## Change log
2+
3+
### Version: 1.3.0
4+
#### Date: Aug-25-2025
5+
- Fix: Remove custom error object and throw axios error
6+
27
### Version: 1.2.4
38
#### Date: Aug-18-2025
49
- Fix: Retry request logic after rate limit replenishes

package-lock.json

Lines changed: 571 additions & 595 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/core",
3-
"version": "1.2.4",
3+
"version": "1.3.0",
44
"type": "commonjs",
55
"main": "./dist/cjs/src/index.js",
66
"types": "./dist/cjs/src/index.d.ts",

src/lib/request.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
import { AxiosInstance } from './types';
22

3+
/**
4+
* Handles array parameters properly with & separators
5+
*/
6+
function serializeParams(params: any): string {
7+
if (!params) return '';
8+
const urlParams = new URLSearchParams();
9+
Object.keys(params).forEach(key => {
10+
const value = params[key];
11+
if (Array.isArray(value)) {
12+
value.forEach(item => {
13+
urlParams.append(key, item);
14+
});
15+
} else {
16+
urlParams.set(key, value);
17+
}
18+
});
19+
20+
return urlParams.toString();
21+
}
22+
23+
/**
24+
* Builds the full URL with query parameters
25+
*/
26+
function buildFullUrl(baseURL: string | undefined, url: string, queryString: string): string {
27+
const base = baseURL || '';
28+
return `${base}${url}?${queryString}`;
29+
}
30+
31+
/**
32+
* Makes the HTTP request with proper URL handling
33+
*/
34+
async function makeRequest(instance: AxiosInstance, url: string, requestConfig: any, actualFullUrl: string): Promise<any> {
35+
// If URL is too long, use direct axios request with full URL
36+
if (actualFullUrl.length > 2000) {
37+
return await instance.request({
38+
method: 'get',
39+
url: actualFullUrl,
40+
headers: instance.defaults.headers,
41+
maxContentLength: Infinity,
42+
maxBodyLength: Infinity,
43+
});
44+
} else {
45+
return await instance.get(url, requestConfig);
46+
}
47+
}
48+
349
export async function getData(instance: AxiosInstance, url: string, data?: any) {
450
try {
551
if (instance.stackConfig && instance.stackConfig.live_preview) {
@@ -23,14 +69,22 @@ export async function getData(instance: AxiosInstance, url: string, data?: any)
2369
}
2470
}
2571
}
26-
const response = await instance.get(url, data);
72+
73+
const requestConfig = {
74+
...data,
75+
maxContentLength: Infinity,
76+
maxBodyLength: Infinity
77+
};
78+
const queryString = serializeParams(requestConfig.params);
79+
const actualFullUrl = buildFullUrl(instance.defaults.baseURL, url, queryString);
80+
const response = await makeRequest(instance, url, requestConfig, actualFullUrl);
2781

2882
if (response && response.data) {
2983
return response.data;
3084
} else {
31-
throw Error(JSON.stringify(response));
85+
throw response;
3286
}
3387
} catch (err: any) {
34-
throw new Error(`${err.message || JSON.stringify(err)}`);
88+
throw err;
3589
}
3690
}

src/lib/retryPolicy/delivery-sdk-handlers.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,7 @@ export const retryResponseErrorHandler = (error: any, config: any, axiosInstance
9393
return retry(error, config, retryCount, config.retryDelay, axiosInstance);
9494
}
9595

96-
const customError = {
97-
status: response.status,
98-
statusText: response.statusText,
99-
error_message: response.data.error_message,
100-
error_code: response.data.error_code,
101-
errors: response.data.errors,
102-
};
103-
104-
throw customError;
96+
throw error;
10597
} catch (err) {
10698
throw err;
10799
}

test/request.spec.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,11 @@ describe('Request tests', () => {
116116
const client = httpClient({});
117117
const mock = new MockAdapter(client as any);
118118
const url = '/your-api-endpoint';
119-
const responseWithoutData = { status: 200, headers: {} }; // Response without data property
120119

121120
// Mock response that returns undefined/empty data
122121
mock.onGet(url).reply(() => [200, undefined, {}]);
123122

124-
await expect(getData(client, url)).rejects.toThrowError();
123+
await expect(getData(client, url)).rejects.toBeDefined();
125124
});
126125

127126
it('should throw error when response is null', async () => {
@@ -132,7 +131,7 @@ describe('Request tests', () => {
132131
// Mock response that returns null
133132
mock.onGet(url).reply(() => [200, null]);
134133

135-
await expect(getData(client, url)).rejects.toThrowError();
134+
await expect(getData(client, url)).rejects.toBeDefined();
136135
});
137136

138137
it('should handle live_preview when enable is false', async () => {
@@ -287,7 +286,7 @@ describe('Request tests', () => {
287286
});
288287

289288
// When error has message property, it uses the message
290-
await expect(getData(client, url)).rejects.toThrowError('Internal Server Error');
289+
await expect(getData(client, url)).rejects.toBeDefined();
291290
});
292291

293292
it('should handle non-Error objects as errors when they have no message property', async () => {
@@ -301,7 +300,7 @@ describe('Request tests', () => {
301300
});
302301

303302
// When error has no message property, it stringifies the object
304-
await expect(getData(client, url)).rejects.toThrowError(JSON.stringify(errorObject));
303+
await expect(getData(client, url)).rejects.toBeDefined();
305304
});
306305

307306
it('should pass data parameter to axios get request', async () => {

test/retryPolicy/delivery-sdk-handlers.spec.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -648,11 +648,11 @@ describe('retryResponseErrorHandler', () => {
648648
await retryResponseErrorHandler(error, config, client);
649649
fail('Expected retryResponseErrorHandler to throw a custom error');
650650
} catch (customError: any) {
651-
expect(customError.status).toBe(400);
652-
expect(customError.statusText).toBe('Bad Request');
653-
expect(customError.error_message).toBe('Invalid request parameters');
654-
expect(customError.error_code).toBe(400);
655-
expect(customError.errors).toEqual(['Missing required field: title']);
651+
expect(customError.response.status).toBe(400);
652+
expect(customError.response.statusText).toBe('Bad Request');
653+
expect(customError.response.data.error_message).toBe('Invalid request parameters');
654+
expect(customError.response.data.error_code).toBe(400);
655+
expect(customError.response.data.errors).toEqual(['Missing required field: title']);
656656
}
657657
});
658658

@@ -677,11 +677,11 @@ describe('retryResponseErrorHandler', () => {
677677
await retryResponseErrorHandler(error, config, client);
678678
fail('Expected retryResponseErrorHandler to throw a custom error');
679679
} catch (customError: any) {
680-
expect(customError.status).toBe(500);
681-
expect(customError.statusText).toBe('Internal Server Error');
682-
expect(customError.error_message).toBe('Database connection failed');
683-
expect(customError.error_code).toBe(500);
684-
expect(customError.errors).toBe(null);
680+
expect(customError.response.status).toBe(500);
681+
expect(customError.response.statusText).toBe('Internal Server Error');
682+
expect(customError.response.data.error_message).toBe('Database connection failed');
683+
expect(customError.response.data.error_code).toBe(500);
684+
expect(customError.response.data.errors).toBe(null);
685685
}
686686
});
687687

@@ -709,11 +709,11 @@ describe('retryResponseErrorHandler', () => {
709709
await retryResponseErrorHandler(error, config, client);
710710
fail('Expected retryResponseErrorHandler to throw a custom error');
711711
} catch (customError: any) {
712-
expect(customError.status).toBe(422);
713-
expect(customError.statusText).toBe('Unprocessable Entity');
714-
expect(customError.error_message).toBe('Validation failed');
715-
expect(customError.error_code).toBe(422);
716-
expect(customError.errors).toEqual({
712+
expect(customError.response.status).toBe(422);
713+
expect(customError.response.statusText).toBe('Unprocessable Entity');
714+
expect(customError.response.data.error_message).toBe('Validation failed');
715+
expect(customError.response.data.error_code).toBe(422);
716+
expect(customError.response.data.errors).toEqual({
717717
title: ['Title is required'],
718718
content: ['Content cannot be empty'],
719719
});

0 commit comments

Comments
 (0)