in libs/payments/cart/src/lib/cart.service.ts [122:234]
private async wrapWithCartCatch<T>(
cartId: string,
arg2: WrapWithCartCatchOptions | (() => Promise<T>),
arg3?: () => Promise<T>
): Promise<T> {
let options: WrapWithCartCatchOptions | undefined;
let method: () => Promise<T>;
if (typeof arg2 === 'function') {
method = arg2;
} else {
options = arg2;
method = arg3 as () => Promise<T>;
}
try {
return await method();
} catch (error) {
// If the error is in the allowlist, rethrow it
if (
error instanceof Error &&
options?.errorAllowList &&
options.errorAllowList.some((ErrorClass) => error instanceof ErrorClass)
) {
throw error;
}
const errorReasonId = resolveErrorInstance(error);
try {
await this.cartManager.finishErrorCart(cartId, {
errorReasonId,
});
const cart = await this.cartManager.fetchCartById(cartId);
if (cart.stripeSubscriptionId) {
const subscription = await this.subscriptionManager.retrieve(
cart.stripeSubscriptionId
);
const invoice = subscription.latest_invoice
? await this.invoiceManager.retrieve(subscription.latest_invoice)
: undefined;
if (invoice) {
switch (invoice.status) {
case 'draft':
await this.invoiceManager.safeFinalizeWithoutAutoAdvance(
invoice.id
);
await this.invoiceManager.void(invoice.id);
break;
case 'open':
case 'uncollectible':
await this.invoiceManager.void(invoice.id);
break;
case 'paid':
throw new CartError('Paid invoice found on failed cart', {
cartId,
stripeCustomerId: cart.stripeCustomerId,
invoiceId: invoice.id,
});
}
}
const paymentIntent =
await this.subscriptionManager.getLatestPaymentIntent(subscription);
if (paymentIntent?.status === 'succeeded') {
throw new CartError('Paid payment intent found on failed cart', {
cartId,
stripeCustomerId: cart.stripeCustomerId,
paymentIntentId: paymentIntent.id,
});
}
try {
if (paymentIntent) {
await this.paymentIntentManager.cancel(paymentIntent.id);
}
} catch (e) {
// swallow the error to allow cancellation of the subscription
Sentry.captureException(e, {
extra: {
cartId,
},
});
}
if (cart.eligibilityStatus === CartEligibilityStatus.CREATE) {
await this.subscriptionManager.cancel(cart.stripeSubscriptionId, {
cancellation_details: {
comment: 'Automatic Cancellation: Cart checkout failed.',
},
});
} else {
this.statsd.increment(
'checkout_failure_subscription_not_cancelled'
);
this.log.log('checkout failed, subscription not canceled', {
eligibility_status: cart.eligibilityStatus,
offering_id: cart.offeringConfigId,
interval: cart.interval,
});
}
}
} catch (e) {
// All errors thrown during the cleanup process should go to Sentry
Sentry.captureException(e, {
extra: {
cartId,
},
});
}
throw error;
}
}