diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.mjs b/services/web/app/src/Features/Subscription/SubscriptionController.mjs index f28ff9b6a4..44c442ff12 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionController.mjs @@ -885,11 +885,22 @@ async function previewSubscription(req, res, next) { } } - const subscriptionChange = - await SubscriptionHandler.promises.previewSubscriptionChange( - userId, - planCode - ) + let subscriptionChange + try { + subscriptionChange = + await SubscriptionHandler.promises.previewSubscriptionChange( + userId, + planCode + ) + } catch (err) { + if ( + err instanceof Error && + err.constructor.name === 'PaymentServiceResourceNotFoundError' + ) { + return res.redirect('/user/subscription/plans') + } + throw err + } /** @type {PaymentMethod[]} */ const paymentMethod = await Modules.promises.hooks.fire( 'getPaymentMethod', diff --git a/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs b/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs index bc7b9afc3d..b50d36e710 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs +++ b/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs @@ -3,6 +3,7 @@ import sinon from 'sinon' import MockRequest from '../helpers/MockRequest.mjs' import MockResponse from '../helpers/MockResponse.mjs' import SubscriptionErrors from '../../../../app/src/Features/Subscription/Errors.mjs' +import { PaymentServiceResourceNotFoundError } from '../../../../modules/subscriptions/app/src/PaymentServiceErrors.mjs' import SubscriptionHelper from '../../../../app/src/Features/Subscription/SubscriptionHelper.mjs' import { AI_ADD_ON_CODE } from '../../../../app/src/Features/Subscription/AiHelper.mjs' @@ -1772,6 +1773,20 @@ describe('SubscriptionController', function () { expect(ctx.res.render).not.to.have.been.called }) + it('redirects to the plans page when the user has no subscription to preview', async function (ctx) { + ctx.SubscriptionHandler.promises.previewSubscriptionChange = sinon + .stub() + .rejects(new PaymentServiceResourceNotFoundError('no subscription')) + ctx.res.redirect = sinon.stub() + + await ctx.SubscriptionController.previewSubscription(ctx.req, ctx.res) + + expect(ctx.res.redirect).to.have.been.calledWith( + '/user/subscription/plans' + ) + expect(ctx.res.render).not.to.have.been.called + }) + it('passes trialDisabledReason to the view when the user is ineligible for a free trial', async function (ctx) { ctx.req.query = { planCode: 'collaborator_free_trial_7_days' } ctx.PlansLocator.findLocalPlanInSettings.returns({