/** * Quote Expired Error * * Error thrown when a fee quote has expired * * @module features/gas-free/errors/QuoteExpiredError */ import { GasFreeError, GasFreeErrorCode } from './GasFreeError'; import type { FeeQuote } from '../types/FeeQuote'; /** * QuoteExpiredError class * * Thrown when attempting to use an expired fee quote. */ export class QuoteExpiredError extends GasFreeError { /** Quote ID that expired */ public readonly quoteId: string; /** Expiration timestamp */ public readonly expiresAt: number; /** * Create a QuoteExpiredError * * @param quoteId - Quote ID that expired * @param expiresAt - Expiration timestamp * @param additionalContext - Additional context */ constructor( quoteId: string, expiresAt: number, additionalContext?: Record ) { const now = Date.now(); const expiredAgo = now - expiresAt; super( `Fee quote '${quoteId}' expired ${Math.floor( expiredAgo / 1000 )} seconds ago`, GasFreeErrorCode.QUOTE_EXPIRED, undefined, { quoteId, expiresAt, expiredAgo, ...additionalContext, } ); this.name = 'QuoteExpiredError'; this.quoteId = quoteId; this.expiresAt = expiresAt; // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, QuoteExpiredError); } } /** * Create QuoteExpiredError from a FeeQuote * * @param quote - Fee quote that expired * @returns QuoteExpiredError instance */ static fromQuote(quote: FeeQuote): QuoteExpiredError { return new QuoteExpiredError( quote.quoteId, new Date(quote.expiresAt).getTime() ); } /** * Convert error to JSON */ toJSON(): Record { return { ...super.toJSON(), quoteId: this.quoteId, expiresAt: this.expiresAt, }; } }