Search code examples
javakotlinreturntry-catchstripe-payments

Try-catch block in Kotlin -- what to return


fun cancelSubscription(cancelStripeSubscription: CancelStripeSubscription): Subscription {
        Stripe.apiKey = testApiKey
        try {
            val sub = Subscription.retrieve("superSecret")
            return sub.cancel(null)
        } catch (e: StripeException) {
            e.printStackTrace()
        }
    }

Background:

Kotlin newbie here trying to integrate Stripe Billing into a Kotlin app.

Problem:

As e.printStackTrace() is of type Unit according to Kotlin, I see an error that says A 'return' expression required in a function with a block body.({...}).

How can I make this work?

Edit: I am using stripe-java here..


Solution

  • You have a function with a return type of Subscription. This means all possible code paths in the function must end up returning a Subscription or throwing an exception. As you currently have it, your code only returns in the try block. This is a problem; if an exception is thrown it moves into the catch block which has no return statements, nor are there any return statements after the catch block. This means there's a code path that results in no return—thus the error.

    There are at least two solutions to this error:

    1. Don't catch the exception; just let it bubble up out of the method to the caller.

      fun cancelSubscription(cancelStripeSubscription: CancelStripeSubscription): Subscription =
           Subscription.retrieve("superSecret").cancel(null)
      
    2. Make the return type nullable and return null if an exception is thrown.

      fun cancelSubscription(cancelStripeSubscription: CancelStripeSubscription): Subscription? =
          try {
              Subscription.retrieve("superSecret").cancel(null)
          } catch (ex: StripeException) {
              null
          }
      

      I thought about making it nullable but if I make the return type nullable, won't it throw a NullPointerException when it actually throws an error?

      The function itself won't throw an NPE, no. And since the return type is now nullable Kotlin will force you to handle that when you try to use the result. For more information, see Null Safety - Kotlin Programming Language.