Handle timeouts as temporary errors

This commit is contained in:
Samuel Elliott 2022-11-27 16:19:56 +00:00
parent 3821a26038
commit 055fe2dff4
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
3 changed files with 22 additions and 5 deletions

View File

@ -7,7 +7,7 @@ import { ErrorResponse } from '../api/util.js';
import { SavedToken } from './auth/coral.js';
import { SplatNet2RecordsMonitor } from './splatnet2/monitor.js';
import Loop, { LoopResult } from '../util/loop.js';
import { getTitleIdFromEcUrl, hrduration } from '../util/misc.js';
import { getTitleIdFromEcUrl, hrduration, TemporaryErrorSymbol } from '../util/misc.js';
import { CoralUser } from './users.js';
const debug = createDebug('nxapi:nso:notify');
@ -187,7 +187,11 @@ export async function handleError(
err: ErrorResponse<CoralErrorResponse> | NodeJS.ErrnoException,
loop: Loop,
): Promise<LoopResult> {
if ('code' in err && (err as any).type === 'system' && err.code === 'ETIMEDOUT') {
if (TemporaryErrorSymbol in err && err[TemporaryErrorSymbol]) {
debug('Temporary error, waiting %ds before retrying', loop.update_interval, err);
return LoopResult.OK;
} else if ('code' in err && (err as any).type === 'system' && err.code === 'ETIMEDOUT') {
debug('Request timed out, waiting %ds before retrying', loop.update_interval, err);
return LoopResult.OK;

View File

@ -11,6 +11,7 @@ import Loop, { LoopResult } from '../util/loop.js';
import { getTitleIdFromEcUrl } from '../index.js';
import { parseLinkHeader } from '../util/http.js';
import { getUserAgent } from '../util/useragent.js';
import { TemporaryErrorSymbol } from '../util/misc.js';
const debug = createDebug('nxapi:nso:presence');
const debugEventStream = createDebug('nxapi:nso:presence:sse');
@ -619,7 +620,13 @@ export class ZncProxyDiscordPresence extends Loop {
let timeout: NodeJS.Timeout;
let timeout_interval = 90000;
const ontimeout = () => events.dispatchEvent({type: 'error', message: 'Timeout'} as any);
const ontimeout = () => {
const err = new Error('Timeout') as any;
err.type = 'error';
err[TemporaryErrorSymbol] = true;
Object.defineProperty(err, 'detail', {enumerable: false, value: err});
events.dispatchEvent(err);
};
events.onopen = event => {
debugEventStream('EventSource connected', event);
@ -697,7 +704,9 @@ export class ZncProxyDiscordPresence extends Loop {
debugEventStream('EventSource error', event);
events.close();
if ((event as any).message) {
if (event instanceof Error) {
rj(event);
} else if ((event as any).message) {
const err = new Error((event as any).message);
Object.assign(err, event);
rj(err);

View File

@ -1,4 +1,6 @@
export const TemporaryErrorSymbol = Symbol('TemporaryError');
export function getTitleIdFromEcUrl(url: string) {
const match = url.match(/^https:\/\/ec\.nintendo\.com\/apps\/([0-9a-f]{16})\//);
return match?.[1] ?? null;
@ -31,7 +33,9 @@ export function timeoutSignal(ms = 60 * 1000) {
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort(new Error('Timeout'));
const err = new Error('Timeout');
Object.assign(err, TemporaryErrorSymbol, true);
controller.abort(err);
}, ms);
return [controller.signal, () => clearTimeout(timeout), controller] as const;