format: prettify entire project

This commit is contained in:
Rim
2025-04-02 06:50:39 -04:00
parent 86f0782a98
commit 7ccc0be712
1711 changed files with 755867 additions and 235931 deletions

View File

@ -1,23 +1,23 @@
'use strict'
const assert = require('node:assert')
'use strict';
const assert = require('node:assert');
const { kRetryHandlerDefaultRetry } = require('../core/symbols')
const { RequestRetryError } = require('../core/errors')
const WrapHandler = require('./wrap-handler')
const { kRetryHandlerDefaultRetry } = require('../core/symbols');
const { RequestRetryError } = require('../core/errors');
const WrapHandler = require('./wrap-handler');
const {
isDisturbed,
parseRangeHeader,
wrapRequestBody
} = require('../core/util')
wrapRequestBody,
} = require('../core/util');
function calculateRetryAfterHeader (retryAfter) {
const retryTime = new Date(retryAfter).getTime()
return isNaN(retryTime) ? 0 : retryTime - Date.now()
function calculateRetryAfterHeader(retryAfter) {
const retryTime = new Date(retryAfter).getTime();
return isNaN(retryTime) ? 0 : retryTime - Date.now();
}
class RetryHandler {
constructor (opts, { dispatch, handler }) {
const { retryOptions, ...dispatchOpts } = opts
constructor(opts, { dispatch, handler }) {
const { retryOptions, ...dispatchOpts } = opts;
const {
// Retry scoped
retry: retryFn,
@ -29,12 +29,12 @@ class RetryHandler {
methods,
errorCodes,
retryAfter,
statusCodes
} = retryOptions ?? {}
statusCodes,
} = retryOptions ?? {};
this.dispatch = dispatch
this.handler = WrapHandler.wrap(handler)
this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }
this.dispatch = dispatch;
this.handler = WrapHandler.wrap(handler);
this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) };
this.retryOpts = {
retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry],
retryAfter: retryAfter ?? true,
@ -56,31 +56,31 @@ class RetryHandler {
'EHOSTDOWN',
'EHOSTUNREACH',
'EPIPE',
'UND_ERR_SOCKET'
]
}
'UND_ERR_SOCKET',
],
};
this.retryCount = 0
this.retryCountCheckpoint = 0
this.headersSent = false
this.start = 0
this.end = null
this.etag = null
this.retryCount = 0;
this.retryCountCheckpoint = 0;
this.headersSent = false;
this.start = 0;
this.end = null;
this.etag = null;
}
onRequestStart (controller, context) {
onRequestStart(controller, context) {
if (!this.headersSent) {
this.handler.onRequestStart?.(controller, context)
this.handler.onRequestStart?.(controller, context);
}
}
onRequestUpgrade (controller, statusCode, headers, socket) {
this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket)
onRequestUpgrade(controller, statusCode, headers, socket) {
this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket);
}
static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) {
const { statusCode, code, headers } = err
const { method, retryOptions } = opts
static [kRetryHandlerDefaultRetry](err, { state, opts }, cb) {
const { statusCode, code, headers } = err;
const { method, retryOptions } = opts;
const {
maxRetries,
minTimeout,
@ -88,20 +88,20 @@ class RetryHandler {
timeoutFactor,
statusCodes,
errorCodes,
methods
} = retryOptions
const { counter } = state
methods,
} = retryOptions;
const { counter } = state;
// Any code that is not a Undici's originated and allowed to retry
if (code && code !== 'UND_ERR_REQ_RETRY' && !errorCodes.includes(code)) {
cb(err)
return
cb(err);
return;
}
// If a set of method are provided and the current method is not in the list
if (Array.isArray(methods) && !methods.includes(method)) {
cb(err)
return
cb(err);
return;
}
// If a set of status code are provided and the current status code is not in the list
@ -110,52 +110,53 @@ class RetryHandler {
Array.isArray(statusCodes) &&
!statusCodes.includes(statusCode)
) {
cb(err)
return
cb(err);
return;
}
// If we reached the max number of retries
if (counter > maxRetries) {
cb(err)
return
cb(err);
return;
}
let retryAfterHeader = headers?.['retry-after']
let retryAfterHeader = headers?.['retry-after'];
if (retryAfterHeader) {
retryAfterHeader = Number(retryAfterHeader)
retryAfterHeader = Number.isNaN(retryAfterHeader)
? calculateRetryAfterHeader(headers['retry-after'])
: retryAfterHeader * 1e3 // Retry-After is in seconds
retryAfterHeader = Number(retryAfterHeader);
retryAfterHeader =
Number.isNaN(retryAfterHeader) ?
calculateRetryAfterHeader(headers['retry-after'])
: retryAfterHeader * 1e3; // Retry-After is in seconds
}
const retryTimeout =
retryAfterHeader > 0
? Math.min(retryAfterHeader, maxTimeout)
: Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout)
retryAfterHeader > 0 ?
Math.min(retryAfterHeader, maxTimeout)
: Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout);
setTimeout(() => cb(null), retryTimeout)
setTimeout(() => cb(null), retryTimeout);
}
onResponseStart (controller, statusCode, headers, statusMessage) {
this.retryCount += 1
onResponseStart(controller, statusCode, headers, statusMessage) {
this.retryCount += 1;
if (statusCode >= 300) {
if (this.retryOpts.statusCodes.includes(statusCode) === false) {
this.headersSent = true
this.headersSent = true;
this.handler.onResponseStart?.(
controller,
statusCode,
headers,
statusMessage
)
return
);
return;
} else {
throw new RequestRetryError('Request failed', statusCode, {
headers,
data: {
count: this.retryCount
}
})
count: this.retryCount,
},
});
}
}
@ -166,120 +167,120 @@ class RetryHandler {
// should not be retried because it would result in downstream
// wrongly concatenate multiple responses.
if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) {
throw new RequestRetryError('server does not support the range header and the payload was partially consumed', statusCode, {
headers,
data: { count: this.retryCount }
})
throw new RequestRetryError(
'server does not support the range header and the payload was partially consumed',
statusCode,
{
headers,
data: { count: this.retryCount },
}
);
}
const contentRange = parseRangeHeader(headers['content-range'])
const contentRange = parseRangeHeader(headers['content-range']);
// If no content range
if (!contentRange) {
throw new RequestRetryError('Content-Range mismatch', statusCode, {
headers,
data: { count: this.retryCount }
})
data: { count: this.retryCount },
});
}
// Let's start with a weak etag check
if (this.etag != null && this.etag !== headers.etag) {
throw new RequestRetryError('ETag mismatch', statusCode, {
headers,
data: { count: this.retryCount }
})
data: { count: this.retryCount },
});
}
const { start, size, end = size ? size - 1 : null } = contentRange
const { start, size, end = size ? size - 1 : null } = contentRange;
assert(this.start === start, 'content-range mismatch')
assert(this.end == null || this.end === end, 'content-range mismatch')
assert(this.start === start, 'content-range mismatch');
assert(this.end == null || this.end === end, 'content-range mismatch');
return
return;
}
if (this.end == null) {
if (statusCode === 206) {
// First time we receive 206
const range = parseRangeHeader(headers['content-range'])
const range = parseRangeHeader(headers['content-range']);
if (range == null) {
this.headersSent = true
this.headersSent = true;
this.handler.onResponseStart?.(
controller,
statusCode,
headers,
statusMessage
)
return
);
return;
}
const { start, size, end = size ? size - 1 : null } = range
const { start, size, end = size ? size - 1 : null } = range;
assert(
start != null && Number.isFinite(start),
'content-range mismatch'
)
assert(end != null && Number.isFinite(end), 'invalid content-length')
);
assert(end != null && Number.isFinite(end), 'invalid content-length');
this.start = start
this.end = end
this.start = start;
this.end = end;
}
// We make our best to checkpoint the body for further range headers
if (this.end == null) {
const contentLength = headers['content-length']
this.end = contentLength != null ? Number(contentLength) - 1 : null
const contentLength = headers['content-length'];
this.end = contentLength != null ? Number(contentLength) - 1 : null;
}
assert(Number.isFinite(this.start))
assert(Number.isFinite(this.start));
assert(
this.end == null || Number.isFinite(this.end),
'invalid content-length'
)
);
this.resume = true
this.etag = headers.etag != null ? headers.etag : null
this.resume = true;
this.etag = headers.etag != null ? headers.etag : null;
// Weak etags are not useful for comparison nor cache
// for instance not safe to assume if the response is byte-per-byte
// equal
if (
this.etag != null &&
this.etag[0] === 'W' &&
this.etag[1] === '/'
) {
this.etag = null
if (this.etag != null && this.etag[0] === 'W' && this.etag[1] === '/') {
this.etag = null;
}
this.headersSent = true
this.headersSent = true;
this.handler.onResponseStart?.(
controller,
statusCode,
headers,
statusMessage
)
);
} else {
throw new RequestRetryError('Request failed', statusCode, {
headers,
data: { count: this.retryCount }
})
data: { count: this.retryCount },
});
}
}
onResponseData (controller, chunk) {
this.start += chunk.length
onResponseData(controller, chunk) {
this.start += chunk.length;
this.handler.onResponseData?.(controller, chunk)
this.handler.onResponseData?.(controller, chunk);
}
onResponseEnd (controller, trailers) {
this.retryCount = 0
return this.handler.onResponseEnd?.(controller, trailers)
onResponseEnd(controller, trailers) {
this.retryCount = 0;
return this.handler.onResponseEnd?.(controller, trailers);
}
onResponseError (controller, err) {
onResponseError(controller, err) {
if (controller?.aborted || isDisturbed(this.opts.body)) {
this.handler.onResponseError?.(controller, err)
return
this.handler.onResponseError?.(controller, err);
return;
}
// We reconcile in case of a mix between network errors
@ -288,55 +289,55 @@ class RetryHandler {
// We count the difference between the last checkpoint and the current retry count
this.retryCount =
this.retryCountCheckpoint +
(this.retryCount - this.retryCountCheckpoint)
(this.retryCount - this.retryCountCheckpoint);
} else {
this.retryCount += 1
this.retryCount += 1;
}
this.retryOpts.retry(
err,
{
state: { counter: this.retryCount },
opts: { retryOptions: this.retryOpts, ...this.opts }
opts: { retryOptions: this.retryOpts, ...this.opts },
},
onRetry.bind(this)
)
);
/**
* @this {RetryHandler}
* @param {Error} [err]
* @returns
*/
function onRetry (err) {
function onRetry(err) {
if (err != null || controller?.aborted || isDisturbed(this.opts.body)) {
return this.handler.onResponseError?.(controller, err)
return this.handler.onResponseError?.(controller, err);
}
if (this.start !== 0) {
const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }
const headers = { range: `bytes=${this.start}-${this.end ?? ''}` };
// Weak etag check - weak etags will make comparison algorithms never match
if (this.etag != null) {
headers['if-match'] = this.etag
headers['if-match'] = this.etag;
}
this.opts = {
...this.opts,
headers: {
...this.opts.headers,
...headers
}
}
...headers,
},
};
}
try {
this.retryCountCheckpoint = this.retryCount
this.dispatch(this.opts, this)
this.retryCountCheckpoint = this.retryCount;
this.dispatch(this.opts, this);
} catch (err) {
this.handler.onResponseError?.(controller, err)
this.handler.onResponseError?.(controller, err);
}
}
}
}
module.exports = RetryHandler
module.exports = RetryHandler;