import { ForgeInvocationError, ForgeInvocationErrorOptions, InvocationStatusCode, } from '@atlassian/forge-graphql-types'; export class ForgeInvocationErrorResponseBuilderError extends Error {} export class ForgeInvocationErrorResponse { private error: string; private statusCode: InvocationStatusCode; private options: ForgeInvocationErrorOptions; constructor( error: string, statusCode: InvocationStatusCode, options: ForgeInvocationErrorOptions, ) { this.error = error; this.statusCode = statusCode; this.options = options; } private validateOptions(): void { const BACKOFF_TIME_OPTION = 'backoffTimeInSeconds'; const supportedOptions = [BACKOFF_TIME_OPTION]; for (const [option, optionValue] of Object.entries(this.options)) { if (!supportedOptions.includes(option)) { throw new ForgeInvocationErrorResponseBuilderError( `${option} is not a valid option.`, ); } if ( option === BACKOFF_TIME_OPTION && (typeof optionValue !== 'number' || optionValue < 0) ) { throw new ForgeInvocationErrorResponseBuilderError( `${option} has invalid value.`, ); } } } private validate(): void { if (typeof this.error !== 'string' || this.error.length === 0) { throw new ForgeInvocationErrorResponseBuilderError( 'Error must be a string.', ); } if (!Object.values(InvocationStatusCode).includes(this.statusCode)) { console.log( `Unsupported status code: ${this.statusCode} in ForgeInvocationErrorResponse class`, ); this.statusCode = InvocationStatusCode.INTERNAL_SERVER_ERROR; } if (typeof this.options !== 'object') { throw new ForgeInvocationErrorResponseBuilderError( 'Options object is not provided.', ); } this.validateOptions(); } build(): ForgeInvocationError { this.validate(); return { error: this.error, statusCode: this.statusCode, options: this.options, }; } }