Ensure payment errors are propagated to the UI

Problem

We're seeing errors in onSubscriptionError like this Sentry error report and this

Looking at the function nothing seems off at first glance.

// subscription_form.js
function onSubscriptonError(errors) {
  if (errors.attributes && errors.attributes.indexOf('coupon') >= 0) {
    $('#coupon-error').text('Invalid code');
  } else {
    ZuoraSubscriptionErrorHandler.redirectToErrorPage(errors);
  }
}

This fatal error is occurring because onSubscriptonError (I also just noticed there's a typo there) is being called with with an undefined object.

This happens in the callback here

// subscription_form.js
ZuoraSubscription.update(data, result => {
    if (result.success) {
      on_success(result);
    } else {
      onSubscriptonError(result.errors);
    }

    window.scrollTo(0, 0);

    // Whatever the response is always enable the submit button
    $('#preview-subscription').removeAttr('disabled');
  });

What does the user see?

The user just sees the loading page spinning without resolving

How should we have noticed this?

  • Look at Sentry error reports; however this isn't part of our workflow
  • Have tests in place for this scenario
  • Use static types to catch these problems; If static type checking was in place the computer would catch this error before we'd ship this piece of code

Proposal

A patch here is to ensure we're not passing undefined to onSubscriptonError

onSubscriptonError(result.errors || {code: 500, message: 'Unknown error occurred, this has been logged in our service; Please open a Support ticket if the problem persists' });

The more serious problem is that we didn't catch this sooner. We should

  • Incorporate Sentry into our workflow (all fulfillment engineers should have Sentry notifications on? Open tickets automatically for new error reports?)
  • Increase our test coverage
  • Seriously consider adopting something like TypeScript
Edited by Ragnar Hardarson