Skip to content

Commit

Permalink
Fix null XHR response handling (#6842)
Browse files Browse the repository at this point in the history
* Prevent Inivalid State exception thrown by reading xhr.responseText when xhr.response is null and responseType is not text or empty
  • Loading branch information
robwalch authored Nov 14, 2024
1 parent 4b61208 commit 8593c31
Showing 1 changed file with 52 additions and 49 deletions.
101 changes: 52 additions & 49 deletions src/utils/xhr-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,59 +204,62 @@ class XhrLoader implements Loader<LoaderContext> {
xhr.onprogress = null;
const status = xhr.status;
// http status between 200 to 299 are all successful
const useResponse = xhr.responseType !== 'text';
if (
status >= 200 &&
status < 300 &&
((useResponse && xhr.response) || xhr.responseText !== null)
) {
stats.loading.end = Math.max(
self.performance.now(),
stats.loading.first,
);
const data = useResponse ? xhr.response : xhr.responseText;
const len =
xhr.responseType === 'arraybuffer' ? data.byteLength : data.length;
stats.loaded = stats.total = len;
stats.bwEstimate =
(stats.total * 8000) / (stats.loading.end - stats.loading.first);
if (!this.callbacks) {
return;
}
const onProgress = this.callbacks.onProgress;
if (onProgress) {
onProgress(stats, context, data, xhr);
}
if (!this.callbacks) {
const useResponseText =
xhr.responseType === 'text' ? xhr.responseText : null;
if (status >= 200 && status < 300) {
const data = useResponseText ?? xhr.response;
if (data != null) {
stats.loading.end = Math.max(
self.performance.now(),
stats.loading.first,
);
const len =
xhr.responseType === 'arraybuffer'
? data.byteLength
: data.length;
stats.loaded = stats.total = len;
stats.bwEstimate =
(stats.total * 8000) / (stats.loading.end - stats.loading.first);
if (!this.callbacks) {
return;
}
const onProgress = this.callbacks.onProgress;
if (onProgress) {
onProgress(stats, context, data, xhr);
}
if (!this.callbacks) {
return;
}
const response: LoaderResponse = {
url: xhr.responseURL,
data: data,
code: status,
};

this.callbacks.onSuccess(response, stats, context, xhr);
return;
}
const response: LoaderResponse = {
url: xhr.responseURL,
data: data,
code: status,
};
}

this.callbacks.onSuccess(response, stats, context, xhr);
// Handle bad status or nullish response
const retryConfig = config.loadPolicy.errorRetry;
const retryCount = stats.retry;
// if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
const response: LoaderResponse = {
url: context.url,
data: undefined,
code: status,
};
if (shouldRetry(retryConfig, retryCount, false, response)) {
this.retry(retryConfig);
} else {
const retryConfig = config.loadPolicy.errorRetry;
const retryCount = stats.retry;
// if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
const response: LoaderResponse = {
url: context.url,
data: undefined,
code: status,
};
if (shouldRetry(retryConfig, retryCount, false, response)) {
this.retry(retryConfig);
} else {
logger.error(`${status} while loading ${context.url}`);
this.callbacks!.onError(
{ code: status, text: xhr.statusText },
context,
xhr,
stats,
);
}
logger.error(`${status} while loading ${context.url}`);
this.callbacks!.onError(
{ code: status, text: xhr.statusText },
context,
xhr,
stats,
);
}
}
}
Expand Down

0 comments on commit 8593c31

Please sign in to comment.