in uui-core/src/services/ApiContext.ts [218:287]
private handleResponse(call: ApiCall, response: Response) {
call.finishedAt = new Date();
call.httpStatus = response.status;
if (response.ok) {
this.analyticsCtx?.sendEvent(
{
name: 'timing_complete',
parameters: {
value: call.finishedAt.getTime() - call.startedAt.getTime(),
name: call.name,
event_category: window.location.pathname,
},
},
'apiTiming',
);
if (response.status === 204) {
return this.resolveCall(call, null);
}
call.options.parseResponse(response)
.then((result) => {
call.responseData = result;
this.resolveCall(call, result);
})
.catch((e) => {
if (e?.name === 'AbortError') {
this.removeFromQueue(call);
return;
}
/* Problem with response JSON parsing */
call.status = 'error';
this.setStatus('error');
call.reject(e);
});
} else if (
/* Network and server-related problems. We'll ping the server and then retry the call in this case. */
(response.status === 408
|| /* Request Timeout */ response.status === 420
|| /* Enhance Your Calm */ response.status === 429
|| /* Too Many Requests */ response.status === 502
|| /* Bad Gateway */ response.status === 503
|| /* Service Unavailable */ response.status === 504)
&& /* Gateway Timeout */ call.attemptsCount < 2 /*
There can be cases, when server returns some of these states, while /ping works.
To not enter infinite loop in this case, we limit number of retries.
*/
) {
let reason: ApiRecoveryReason = 'connection-lost';
if (response.status === 420 || response.status === 429) {
reason = 'server-overload';
}
if (response.status === 503) {
reason = 'maintenance';
}
this.handleApiError(call, reason);
} else if (response.status === 401) {
/* Authentication cookies invalidated */ this.handleApiError(call, 'auth-lost');
} else {
// Try to parse response
call.options.parseResponse(response)
.catch(() => null) // Ignore parsing errors
.then((result) => {
call.responseData = result;
this.handleApiError(call);
});
}
}