|
@@ -445,71 +445,75 @@ export class Client {
|
|
|
|
|
|
// XXX(epurkhiser): We migrated off of jquery, so for now we have a
|
|
|
// compatibility layer which mimics that of the jquery response objects.
|
|
|
- fetchRequest.then(async response => {
|
|
|
- // The Response's body can only be resolved/used at most once.
|
|
|
- // So we clone the response so we can resolve the body content as text content.
|
|
|
- // Response objects need to be cloned before its body can be used.
|
|
|
- const responseClone = response.clone();
|
|
|
-
|
|
|
- let responseJSON: any;
|
|
|
- let responseText: any;
|
|
|
-
|
|
|
- const {status, statusText} = response;
|
|
|
- let {ok} = response;
|
|
|
- let errorReason = 'Request not OK'; // the default error reason
|
|
|
-
|
|
|
- // Try to get text out of the response no matter the status
|
|
|
- try {
|
|
|
- responseText = await response.text();
|
|
|
- } catch (error) {
|
|
|
- ok = false;
|
|
|
- if (error.name === 'AbortError') {
|
|
|
- errorReason = 'Request was aborted';
|
|
|
- } else {
|
|
|
- errorReason = error.toString();
|
|
|
- }
|
|
|
- }
|
|
|
+ fetchRequest
|
|
|
+ .then(async response => {
|
|
|
+ // The Response's body can only be resolved/used at most once.
|
|
|
+ // So we clone the response so we can resolve the body content as text content.
|
|
|
+ // Response objects need to be cloned before its body can be used.
|
|
|
+ const responseClone = response.clone();
|
|
|
|
|
|
- const responseContentType = response.headers.get('content-type');
|
|
|
- const isResponseJSON = responseContentType?.includes('json');
|
|
|
+ let responseJSON: any;
|
|
|
+ let responseText: any;
|
|
|
|
|
|
- const isStatus3XX = status >= 300 && status < 400;
|
|
|
- if (status !== 204 && !isStatus3XX) {
|
|
|
+ const {status, statusText} = response;
|
|
|
+ let {ok} = response;
|
|
|
+ let errorReason = 'Request not OK'; // the default error reason
|
|
|
+
|
|
|
+ // Try to get text out of the response no matter the status
|
|
|
try {
|
|
|
- responseJSON = await responseClone.json();
|
|
|
+ responseText = await response.text();
|
|
|
} catch (error) {
|
|
|
+ ok = false;
|
|
|
if (error.name === 'AbortError') {
|
|
|
- ok = false;
|
|
|
errorReason = 'Request was aborted';
|
|
|
- } else if (isResponseJSON && error instanceof SyntaxError) {
|
|
|
- // If the MIME type is `application/json` but decoding failed,
|
|
|
- // this should be an error.
|
|
|
- ok = false;
|
|
|
- errorReason = 'JSON parse error';
|
|
|
+ } else {
|
|
|
+ errorReason = error.toString();
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- const responseMeta: ResponseMeta = {
|
|
|
- status,
|
|
|
- statusText,
|
|
|
- responseJSON,
|
|
|
- responseText,
|
|
|
- getResponseHeader: (header: string) => response.headers.get(header),
|
|
|
- };
|
|
|
-
|
|
|
- // Respect the response content-type header
|
|
|
- const responseData = isResponseJSON ? responseJSON : responseText;
|
|
|
-
|
|
|
- if (ok) {
|
|
|
- successHandler(responseMeta, statusText, responseData);
|
|
|
- } else {
|
|
|
- globalErrorHandlers.forEach(handler => handler(responseMeta));
|
|
|
- errorHandler(responseMeta, statusText, errorReason);
|
|
|
- }
|
|
|
+ const responseContentType = response.headers.get('content-type');
|
|
|
+ const isResponseJSON = responseContentType?.includes('json');
|
|
|
|
|
|
- completeHandler(responseMeta, statusText);
|
|
|
- });
|
|
|
+ const isStatus3XX = status >= 300 && status < 400;
|
|
|
+ if (status !== 204 && !isStatus3XX) {
|
|
|
+ try {
|
|
|
+ responseJSON = await responseClone.json();
|
|
|
+ } catch (error) {
|
|
|
+ if (error.name === 'AbortError') {
|
|
|
+ ok = false;
|
|
|
+ errorReason = 'Request was aborted';
|
|
|
+ } else if (isResponseJSON && error instanceof SyntaxError) {
|
|
|
+ // If the MIME type is `application/json` but decoding failed,
|
|
|
+ // this should be an error.
|
|
|
+ ok = false;
|
|
|
+ errorReason = 'JSON parse error';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const responseMeta: ResponseMeta = {
|
|
|
+ status,
|
|
|
+ statusText,
|
|
|
+ responseJSON,
|
|
|
+ responseText,
|
|
|
+ getResponseHeader: (header: string) => response.headers.get(header),
|
|
|
+ };
|
|
|
+
|
|
|
+ // Respect the response content-type header
|
|
|
+ const responseData = isResponseJSON ? responseJSON : responseText;
|
|
|
+
|
|
|
+ if (ok) {
|
|
|
+ successHandler(responseMeta, statusText, responseData);
|
|
|
+ } else {
|
|
|
+ globalErrorHandlers.forEach(handler => handler(responseMeta));
|
|
|
+ errorHandler(responseMeta, statusText, errorReason);
|
|
|
+ }
|
|
|
+
|
|
|
+ completeHandler(responseMeta, statusText);
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ // Ignore all failed requests
|
|
|
+ });
|
|
|
|
|
|
const request = new Request(fetchRequest, aborter);
|
|
|
this.activeRequests[id] = request;
|