FutureMind/koru

Undeclared Errors in Swift

Closed this issue · 3 comments

837 commented

The subscribe function either needs to have a Throws(Exception::class) annotation or shouldn't be able to throw an exception.
Undeclared thrown Errors cause unreadable Swift error messages and don't show the real issue.
For example fun subscribe(scope,...) can throw IllegalArgumentException("To use implicit scope, you have to provide it via @ToNativeClass.launchOnScope and @ExportedScopeProvider."), this message is not visible in Swift though.
Therefore undeclared Exceptions will cause confusion.

Maybe something like this. Drawback is that we now have a nullable Job...

fun subscribe(
      onSuccess: (item: T) -> Unit,
      onThrow: (error: Throwable) -> Unit
  ) = subscribe(
      scope = scopeProvider?.scope,
      onSuccess = onSuccess,
      onThrow = onThrow
  )

  fun subscribe(
      scope: CoroutineScope?,
      onSuccess: (item: T) -> Unit,
      onThrow: (error: Throwable) -> Unit
  ): Job?  {
      if(scope==null){
          onThrow(IllegalArgumentException("To use implicit scope, you have to provide it via @ToNativeClass.launchOnScope and @ExportedScopeProvider."))
      }
      return scope?.launch {
          try {
              onSuccess(suspender().freeze())
          } catch (error: Throwable) {
              onThrow(error.freeze())
          }
      } 
  } 

Good catch :)

Nullable Job is a bad thing, we should definitely throw here as it's an illegal use - nullability would be too ambiguous. I think, however, that we only need to declare the error with @Throws annotation and we should be good to go. Will check and release if it works fine.

Hmmm, I checked it and I get this message in the logs.

Function doesn't have or inherit @Throws annotation and thus exception isn't propagated from Kotlin to Objective-C/Swift as NSError.
It is considered unexpected and unhandled instead. Program will be terminated.
Uncaught Kotlin exception: kotlin.IllegalArgumentException: To use implicit scope, you have to provide it via @ToNativeClass.launchOnScope and @ExportedScopeProvider.

It will not be part of the stacktrace, but kotlin errors never are (unfortunately). They either get propagated to swift as checked exceptions or just crash the app as fatal errors - and are visible in logs (see screenshot). We need the latter - Koru cannot do anything about this situation other than tell you via a fatal error what you need to do to make it work.

errorscrenshot

Closing as stale.