Skip to content

ApiResponse.suspendOf does not handle exceptions #485

@glovebx

Description

@glovebx

Please complete the following information:

Library Version: v2.1.2
Affected Device(s): N/A. This issue is not device-specific and affects the library's core logic on all platforms.
Describe the Bug:

The ApiResponse.suspendOf extension function does not handle exceptions that are thrown from within the executed suspend lambda (f).

In the current implementation, the suspend lambda is invoked directly without being wrapped in a try-catch block:

Kotlin

public suspend inline fun suspendOf(
tag: Any? = null,
crossinline f: suspend () -> T,
): ApiResponse {
val result = f() // <-- Exception thrown here is not handled
return of(tag = tag) { result }
}
If the lambda f throws any exception (e.g., IOException from a network call, a custom business logic exception, a parsing error, etc.), the exception is not caught. It propagates up the call stack, and if it remains unhandled by the caller, it will lead to an application crash. This defeats the purpose of using a wrapper like ApiResponse, which is intended to safely encapsulate both success and failure states.

Expected Behavior:

The suspendOf function should be robust and safely handle all exceptions (except for CancellationException).

It is expected that any Exception thrown within the suspend lambda f would be caught internally by the suspendOf function. Upon catching an exception, the function should return an ApiResponse.Failure instance containing the caught exception.

This allows the consumer of the API to reliably handle both success and failure cases through the ApiResponse sealed interface, preventing unexpected crashes and enabling graceful error handling.

For example:

Kotlin

suspend fun fetchSomeData(): ApiResponse {
return ApiResponse.suspendOf {
// This network call might throw an IOException
myApi.getData()
}
}

// The caller can then safely handle the result
val response = fetchSomeData()
when (response) {
is ApiResponse.Success -> { /* Handle success / }
is ApiResponse.Failure -> { /
Handle failure without the app crashing */ }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions