Skip to content

Commit 4a31d13

Browse files
authored
REF: DX-1182 Prevent TypeError when API returns error responses (#47)
* Prevent TypeError when API returns error responses Improvements: DX-1182 Previously, when the API returned non-404 error responses (401, 500, etc.), the code would attempt to call .map() on the error object, resulting in: "TypeError: responseBody.map is not a function" Changes: - Add validation for HTTP status codes before processing response - Check if responseBody is an array before calling .map() - Extract and include error details from API error responses - Provide clear, actionable error messages Example error messages: - "Failed to fetch revisions (HTTP 401): unauthorized" - "Expected array of revisions, but got object: {...}" This fix addresses transient API failures and authentication issues that previously resulted in cryptic TypeErrors. * Address issues pointed out by automated review.
1 parent 7e7947d commit 4a31d13

1 file changed

Lines changed: 30 additions & 3 deletions

File tree

lib/rest-client.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,40 @@ module.exports = CoreObject.extend({
109109
}
110110

111111
return denodeify(this._request.get)({ uri, qs: qs }).then(function (response) {
112-
var responseBody =
113-
useReleaseEndpoint && isSummaryEndpoint ? response.body.filter((rev) => rev.app === appName) : response.body;
114-
112+
// Handle 404 as empty revision list
115113
if (response.statusCode == 404) {
116114
return [];
117115
}
118116

117+
// Handle non-2xx status codes
118+
if (response.statusCode < 200 || response.statusCode >= 300) {
119+
var errorMessage = 'Failed to fetch revisions (HTTP ' + response.statusCode + ')';
120+
121+
// Try to extract error details from response body
122+
if (response.body && response.body.errors && Array.isArray(response.body.errors)) {
123+
var errorDetails = response.body.errors
124+
.map(function (err) {
125+
return err.detail || err.message || JSON.stringify(err);
126+
})
127+
.join(', ');
128+
errorMessage += ': ' + errorDetails;
129+
} else if (response.body && typeof response.body === 'object') {
130+
errorMessage += ': ' + JSON.stringify(response.body);
131+
}
132+
133+
return Promise.reject(new Error(errorMessage));
134+
}
135+
136+
if (!Array.isArray(response.body)) {
137+
var bodyType = response.body === null ? 'null' : typeof response.body;
138+
return Promise.reject(
139+
new Error('Expected array of revisions, but got ' + bodyType + ': ' + JSON.stringify(response.body)),
140+
);
141+
}
142+
143+
var responseBody =
144+
useReleaseEndpoint && isSummaryEndpoint ? response.body.filter((rev) => rev.app === appName) : response.body;
145+
119146
return responseBody.map(function (revision) {
120147
// ember-cli-deploy-display-revisions expects the timestamp to be either
121148
// a JS Date object or the number of milliseconds since 1970-01-01T00:00:00

0 commit comments

Comments
 (0)