Skip to content

Commit

Permalink
add code to FirebaseFunctionsException
Browse files Browse the repository at this point in the history
  • Loading branch information
nbransby committed Sep 28, 2023
1 parent f7c65b3 commit 436188c
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ actual class HttpsCallableResult constructor(val android: com.google.firebase.fu
}

actual typealias FirebaseFunctionsException = com.google.firebase.functions.FirebaseFunctionsException

actual val FirebaseFunctionsException.code: FunctionsExceptionCode get() = code

actual typealias FunctionsExceptionCode = com.google.firebase.functions.FirebaseFunctionsException.Code

Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,26 @@ expect fun Firebase.functions(app: FirebaseApp): FirebaseFunctions
expect fun Firebase.functions(app: FirebaseApp, region: String): FirebaseFunctions

expect class FirebaseFunctionsException: FirebaseException

@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
expect val FirebaseFunctionsException.code: FunctionsExceptionCode

expect enum class FunctionsExceptionCode {
OK,
CANCELLED,
UNKNOWN,
INVALID_ARGUMENT,
DEADLINE_EXCEEDED,
NOT_FOUND,
ALREADY_EXISTS,
PERMISSION_DENIED,
RESOURCE_EXHAUSTED,
FAILED_PRECONDITION,
ABORTED,
OUT_OF_RANGE,
UNIMPLEMENTED,
INTERNAL,
UNAVAILABLE,
DATA_LOSS,
UNAUTHENTICATED
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@

package dev.gitlive.firebase.functions

import cocoapods.FirebaseFunctions.*
import dev.gitlive.firebase.Firebase
import dev.gitlive.firebase.FirebaseApp
import dev.gitlive.firebase.FirebaseException
import dev.gitlive.firebase.decode
import dev.gitlive.firebase.encode
import cocoapods.FirebaseFunctions.FIRFunctions
import cocoapods.FirebaseFunctions.FIRHTTPSCallable
import cocoapods.FirebaseFunctions.FIRHTTPSCallableResult
import dev.gitlive.firebase.*
import kotlinx.coroutines.CompletableDeferred
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import platform.Foundation.*
import platform.Foundation.NSError

actual val Firebase.functions
get() = FirebaseFunctions(FIRFunctions.functions())
Expand Down Expand Up @@ -58,15 +56,62 @@ actual class HttpsCallableResult constructor(val ios: FIRHTTPSCallableResult) {
decode(strategy, ios.data())
}

actual class FirebaseFunctionsException(message: String): FirebaseException(message)
actual class FirebaseFunctionsException(message: String, val code: FunctionsExceptionCode) : FirebaseException(message)

@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
actual val FirebaseFunctionsException.code: FunctionsExceptionCode get() = code

actual enum class FunctionsExceptionCode {
OK,
CANCELLED,
UNKNOWN,
INVALID_ARGUMENT,
DEADLINE_EXCEEDED,
NOT_FOUND,
ALREADY_EXISTS,
PERMISSION_DENIED,
RESOURCE_EXHAUSTED,
FAILED_PRECONDITION,
ABORTED,
OUT_OF_RANGE,
UNIMPLEMENTED,
INTERNAL,
UNAVAILABLE,
DATA_LOSS,
UNAUTHENTICATED
}
//todo uncomment once https://github.com/firebase/firebase-ios-sdk/issues/11862 fixed
fun NSError.toException() = when(domain) {
// FIRFunctionsErrorDomain -> when(code) {
// FIRFunctionsErrorCodeOK -> FunctionsExceptionCode.OK
// FIRFunctionsErrorCodeCancelled -> FunctionsExceptionCode.CANCELLED
// FIRFunctionsErrorCodeUnknown -> FunctionsExceptionCode.UNKNOWN
// FIRFunctionsErrorCodeInvalidArgument -> FunctionsExceptionCode.INVALID_ARGUMENT
// FIRFunctionsErrorCodeDeadlineExceeded -> FunctionsExceptionCode.DEADLINE_EXCEEDED
// FIRFunctionsErrorCodeNotFound -> FunctionsExceptionCode.NOT_FOUND
// FIRFunctionsErrorCodeAlreadyExists -> FunctionsExceptionCode.ALREADY_EXISTS
// FIRFunctionsErrorCodePermissionDenied -> FunctionsExceptionCode.PERMISSION_DENIED
// FIRFunctionsErrorCodeResourceExhausted -> FunctionsExceptionCode.RESOURCE_EXHAUSTED
// FIRFunctionsErrorCodeFailedPrecondition -> FunctionsExceptionCode.FAILED_PRECONDITION
// FIRFunctionsErrorCodeAborted -> FunctionsExceptionCode.ABORTED
// FIRFunctionsErrorCodeOutOfRange -> FunctionsExceptionCode.OUT_OF_RANGE
// FIRFunctionsErrorCodeUnimplemented -> FunctionsExceptionCode.UNIMPLEMENTED
// FIRFunctionsErrorCodeInternal -> FunctionsExceptionCode.INTERNAL
// FIRFunctionsErrorCodeUnavailable -> FunctionsExceptionCode.UNAVAILABLE
// FIRFunctionsErrorCodeDataLoss -> FunctionsExceptionCode.DATA_LOSS
// FIRFunctionsErrorCodeUnauthenticated -> FunctionsExceptionCode.UNAUTHENTICATED
// else -> FunctionsExceptionCode.UNKNOWN
// }
else -> FunctionsExceptionCode.UNKNOWN
}.let { FirebaseFunctionsException(description!!, it) }

suspend inline fun <T> T.await(function: T.(callback: (NSError?) -> Unit) -> Unit) {
val job = CompletableDeferred<Unit>()
function { error ->
if(error == null) {
job.complete(Unit)
} else {
job.completeExceptionally(FirebaseFunctionsException(error.localizedDescription))
job.completeExceptionally(error.toException())
}
}
job.await()
Expand All @@ -78,7 +123,7 @@ suspend inline fun <T, reified R> T.awaitResult(function: T.(callback: (R?, NSEr
if(error == null) {
job.complete(result)
} else {
job.completeExceptionally(FirebaseFunctionsException(error.localizedDescription))
job.completeExceptionally(error.toException())
}
}
return job.await() as R
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import dev.gitlive.firebase.functions.externals.*
import kotlinx.coroutines.await
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import org.w3c.dom.url.URL
import kotlin.js.json
import dev.gitlive.firebase.functions.externals.HttpsCallableResult as JsHttpsCallableResult

Expand Down Expand Up @@ -55,7 +54,30 @@ actual class HttpsCallableResult constructor(val js: JsHttpsCallableResult) {

}

actual open class FirebaseFunctionsException(code: String?, cause: Throwable): FirebaseException(code, cause)
actual class FirebaseFunctionsException(cause: Throwable, val code: FunctionsExceptionCode) : FirebaseException(code.toString(), cause)

@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
actual val FirebaseFunctionsException.code: FunctionsExceptionCode get() = code

actual enum class FunctionsExceptionCode {
OK,
CANCELLED,
UNKNOWN,
INVALID_ARGUMENT,
DEADLINE_EXCEEDED,
NOT_FOUND,
ALREADY_EXISTS,
PERMISSION_DENIED,
RESOURCE_EXHAUSTED,
FAILED_PRECONDITION,
ABORTED,
OUT_OF_RANGE,
UNIMPLEMENTED,
INTERNAL,
UNAVAILABLE,
DATA_LOSS,
UNAUTHENTICATED
}

inline fun <T, R> T.rethrow(function: T.() -> R): R = dev.gitlive.firebase.functions.rethrow { function() }

Expand All @@ -65,6 +87,34 @@ inline fun <R> rethrow(function: () -> R): R {
} catch (e: Exception) {
throw e
} catch(e: dynamic) {
throw FirebaseFunctionsException(e.code as String?, e)
throw errorToException(e)
}
}

fun errorToException(e: dynamic) = (e?.code ?: e?.message ?: "")
.toString()
.lowercase()
.let {
when {
"cancelled" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.CANCELLED)
"invalid-argument" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.INVALID_ARGUMENT)
"deadline-exceeded" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.DEADLINE_EXCEEDED)
"not-found" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.NOT_FOUND)
"already-exists" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.ALREADY_EXISTS)
"permission-denied" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.PERMISSION_DENIED)
"resource-exhausted" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.RESOURCE_EXHAUSTED)
"failed-precondition" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.FAILED_PRECONDITION)
"aborted" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.ABORTED)
"out-of-range" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.OUT_OF_RANGE)
"unimplemented" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.UNIMPLEMENTED)
"internal" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.INTERNAL)
"unavailable" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.UNAVAILABLE)
"data-loss" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.DATA_LOSS)
"unauthenticated" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.UNAUTHENTICATED)
"unknown" in it -> FirebaseFunctionsException(e, FunctionsExceptionCode.UNKNOWN)
else -> {
println("Unknown error code in ${JSON.stringify(e)}")
FirebaseFunctionsException(e, FunctionsExceptionCode.UNKNOWN)
}
}
}

0 comments on commit 436188c

Please sign in to comment.