Reputation: 3090
I have an application in a micro service architecture. This application is getting data from different sources and is getting a lot of different error-responses from the various of other applications. Some exceptions, like 404-Not found exceptions can be thrown and returned to the end-user, but other exceptions (bad requests, ++) can't and need to be suppressed by throwing some other exception.
However, I know this can be solved by try-catch
ing the exceptions and moderating what to throw in that matter, but that would involve a lot of code.. sometimes I want to accept 4-5 different exceptions, while other times only 1-2 exceptions.
Anyhow.. I need some help making a higher order function. I want a function that takes one or more "accepted exceptions" as parameters (they're Runtime-exceptions) and throws only the approved exceptions in a try-catch
.
This is what I have tried, but can't seem to get the syntax right (pseudo-code atm.). Any help is really appreciated.
fun getData() {
return supressExceptions(
NotFoundException::class.java,
ForbiddenException::class.java,
AuthorizationException::class.java) {
service.getData()
}
}
private inline fun <T, X : RuntimeException> supressExceptions(vararg approvedException: Class<X>, block: () -> T): T =
try {
block()
} catch (ex: Exception) {
// Loop through the approved exceptions.
// Throw the approved exception
throw ex
// ELSE: do something else if the exception is not approved.
}
Upvotes: 1
Views: 1152
Reputation: 23352
As already mentioned in the comments: from the naming I would have expected that the suppressExceptions rather accepts a parameter of the exceptions to be suppressed.
I wonder whether you actually rather want to check whether a thrown exception is actually an instance of the given exception types, i.e. if also subclasses of the given types should be approved/suppressed or not.
In such a case I would rather use the following code:
inline fun <T> suppressAllExceptions(vararg exceptExceptions: Class<out Exception> = emptyArray(),
block: () -> T) = try {
block()
} catch (e: Exception) {
throw if (exceptExceptions.any { it.isInstance(e) }) {
e
} else SuppressedException(e)
}
You would still use it the same way as you have shown:
suppressAllExceptions {
throw IllegalStateException("i am suppressed soon")
}
suppressAllExceptions(IllegalStateException::class.java,
IllegalArgumentException::class.java) {
throw IllegalStateException("i am not suppressed")
}
class MyIllegalStateException : IllegalStateException()
suppressAllExceptions(IllegalStateException::class.java,
IllegalArgumentException::class.java) {
throw MyIllegalStateException("i am not suppressed neither")
}
The more I think of it: why do you approve different types of exceptions at different places? This doesn't sound right to me. You probably rather want to suppress all exceptions except some well-defined ones and in such a case you do not need such a generic function in the first place, but rather have one suppressing function that contains that well-defined list:
/**
* Suppresses all exceptions except the well-defined ones: [NotFoundException], ...
*/
inline fun <T> suppressExceptions(block: () -> T) = try {
block()
} catch (e: Exception) {
throw when (e) {
is NotFoundException,
is ForbiddenException,
// all the other well-defined non-suppressable types
is AuthorizationException -> e
else -> SuppressedException(e)
}
}
Upvotes: 1
Reputation: 3090
This can be achieved by any
:
private inline fun <T, X : RuntimeException> supressExceptions(vararg approvedException: Class<X>,
block: () -> T): T =
try {
block()
} catch (ex: Exception) {
when {
approvedException.any { ex::class.java == it } -> throw ex
else -> {
throw SupressedException(ex)
}
}
}
any: Returns true if at least one entry matches the given predicate.
Upvotes: 1
Reputation: 7056
Is the below what you're looking for?
private inline fun <T> supressExceptions(vararg approvedException: Class<out RuntimeException>, block: () -> T): T =
try {
block()
} catch (ex: Exception) {
if (approvedException.contains(ex::class.java)) {
// Approved exception
throw ex
}
// ELSE: do something else if the exception is not approved.
else throw Exception("Something else")
}
Upvotes: 2