MCPcopy
hub / github.com/MagicMirrorOrg/MagicMirror / fetch

Method fetch

js/http_fetcher.js:278–349  ·  view source on GitHub ↗

* Performs the HTTP fetch and emits appropriate events * @fires HTTPFetcher#response * @fires HTTPFetcher#error

()

Source from the content-addressed store, hash-verified

276 * @fires HTTPFetcher#error
277 */
278 async fetch () {
279 this.clearTimer();
280
281 let nextDelay = this.reloadInterval;
282 const controller = new AbortController();
283 const timeoutId = setTimeout(() => controller.abort(), this.timeout);
284
285 try {
286 const requestOptions = this.getRequestOptions();
287 // Use undici.fetch when a custom dispatcher is present (e.g. selfSignedCert),
288 // because Node's global fetch and npm undici@8 Agents are incompatible.
289 // For regular requests, use globalThis.fetch so MSW and other interceptors work.
290 const fetchFn = requestOptions.dispatcher ? undiciFetch : globalThis.fetch;
291 const response = await fetchFn(this.url, {
292 ...requestOptions,
293 signal: controller.signal
294 });
295
296 const isSuccessfulResponse = response.ok || response.status === 304;
297
298 if (isSuccessfulResponse) {
299 // Reset error counts on success
300 this.serverErrorCount = 0;
301 this.networkErrorCount = 0;
302
303 /**
304 * Response event - fired when fetch succeeds (including 304)
305 * @event HTTPFetcher#response
306 * @type {Response}
307 */
308 this.emit("response", response);
309 } else {
310 const { delay, errorInfo } = this.#getDelayForResponse(response);
311 nextDelay = delay;
312 this.emit("error", errorInfo);
313 }
314 } catch (error) {
315 const isTimeout = error.name === "AbortError";
316 const message = isTimeout ? `Request timeout after ${this.timeout}ms` : `Network error: ${error.message}`;
317
318 this.networkErrorCount = Math.min(this.networkErrorCount + 1, this.maxRetries);
319 const exhausted = this.networkErrorCount >= this.maxRetries;
320
321 if (exhausted) {
322 nextDelay = this.reloadInterval;
323 Log.error(`${this.logContext}${this.#shortenUrl()} - ${message} Max retries reached, retrying at configured interval (${Math.round(nextDelay / 1000)}s).`);
324 } else {
325 nextDelay = HTTPFetcher.calculateBackoffDelay(this.networkErrorCount, {
326 maxDelay: this.reloadInterval
327 });
328 const retryMsg = `${this.logContext}${this.#shortenUrl()} - ${message} Retry #${this.networkErrorCount} in ${Math.round(nextDelay / 1000)}s.`;
329 if (this.networkErrorCount <= 2) {
330 Log.warn(retryMsg);
331 } else {
332 Log.error(retryMsg);
333 }
334 }
335

Callers 4

scheduleNextFetchMethod · 0.95
startPeriodicFetchMethod · 0.95
corsFunction · 0.80

Calls 7

clearTimerMethod · 0.95
getRequestOptionsMethod · 0.95
#getDelayForResponseMethod · 0.95
#shortenUrlMethod · 0.95
#createErrorInfoMethod · 0.95
scheduleNextFetchMethod · 0.95
calculateBackoffDelayMethod · 0.80

Tested by

no test coverage detected