mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	cover more retryable errors for quote resolution
This commit is contained in:
		
							parent
							
								
									ca7d8b5bff
								
							
						
					
					
						commit
						bb0bc68927
					
				
					 3 changed files with 97 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -25,6 +25,7 @@ import { UtilityService } from '@/core/UtilityService.js';
 | 
			
		|||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { checkHttps } from '@/misc/check-https.js';
 | 
			
		||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
 | 
			
		||||
import { isRetryableError } from '@/misc/is-retryable-error.js';
 | 
			
		||||
import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType, isApObject, isDocument, IApDocument } from '../type.js';
 | 
			
		||||
import { ApLoggerService } from '../ApLoggerService.js';
 | 
			
		||||
import { ApMfmService } from '../ApMfmService.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -707,7 +708,7 @@ export class ApNoteService {
 | 
			
		|||
					this.logger.warn(`Failed to resolve quote "${uri}" for note "${entryUri}": ${e}`);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return (e instanceof StatusError && e.isRetryable);
 | 
			
		||||
				return isRetryableError(e);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								packages/backend/src/misc/is-retryable-error.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/backend/src/misc/is-retryable-error.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
 | 
			
		||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { AbortError } from 'node-fetch';
 | 
			
		||||
import { UnrecoverableError } from 'bullmq';
 | 
			
		||||
import { StatusError } from '@/misc/status-error.js';
 | 
			
		||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns false if the provided value represents a "permanent" error that cannot be retried.
 | 
			
		||||
 * Returns true if the error is retryable, unknown (as all errors are retryable by default), or not an error object.
 | 
			
		||||
 */
 | 
			
		||||
export function isRetryableError(e: unknown): boolean {
 | 
			
		||||
	if (e instanceof StatusError) return e.isRetryable;
 | 
			
		||||
	if (e instanceof IdentifiableError) return e.isRetryable;
 | 
			
		||||
	if (e instanceof UnrecoverableError) return false;
 | 
			
		||||
	if (e instanceof AbortError) return true;
 | 
			
		||||
	if (e instanceof Error) return e.name === 'AbortError';
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								packages/backend/test/unit/misc/is-retryable-error.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								packages/backend/test/unit/misc/is-retryable-error.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
 | 
			
		||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { UnrecoverableError } from 'bullmq';
 | 
			
		||||
import { AbortError } from 'node-fetch';
 | 
			
		||||
import { isRetryableError } from '@/misc/is-retryable-error.js';
 | 
			
		||||
import { StatusError } from '@/misc/status-error.js';
 | 
			
		||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
 | 
			
		||||
 | 
			
		||||
describe(isRetryableError, () => {
 | 
			
		||||
	it('should return true for retryable StatusError', () => {
 | 
			
		||||
		const error = new StatusError('test error', 500);
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
		expect(result).toBeTruthy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	it('should return false for permanent StatusError', () => {
 | 
			
		||||
		const error = new StatusError('test error', 400);
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
		expect(result).toBeFalsy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	it('should return true for retryable IdentifiableError', () => {
 | 
			
		||||
		const error = new IdentifiableError('id', 'message', true);
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
		expect(result).toBeTruthy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	it('should return false for permanent StatusError', () => {
 | 
			
		||||
		const error = new IdentifiableError('id', 'message', false);
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
		expect(result).toBeFalsy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	it('should return false for UnrecoverableError', () => {
 | 
			
		||||
		const error = new UnrecoverableError();
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
		expect(result).toBeFalsy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	it('should return true for typed AbortError', () => {
 | 
			
		||||
		const error = new AbortError();
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
		expect(result).toBeTruthy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	it('should return true for named AbortError', () => {
 | 
			
		||||
		const error = new Error();
 | 
			
		||||
		error.name = 'AbortError';
 | 
			
		||||
 | 
			
		||||
		const result = isRetryableError(error);
 | 
			
		||||
 | 
			
		||||
		expect(result).toBeTruthy();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const nonErrorInputs = [
 | 
			
		||||
		[null, 'null'],
 | 
			
		||||
		[undefined, 'undefined'],
 | 
			
		||||
		[0, 'number'],
 | 
			
		||||
		['string', 'string'],
 | 
			
		||||
		[true, 'boolean'],
 | 
			
		||||
		[[], 'array'],
 | 
			
		||||
		[{}, 'object'],
 | 
			
		||||
	];
 | 
			
		||||
	for (const [input, label] of nonErrorInputs) {
 | 
			
		||||
		it(`should return true for ${label} input`, () => {
 | 
			
		||||
			const result = isRetryableError(input);
 | 
			
		||||
			expect(result).toBeTruthy();
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue