Consider the following function
fun issueAssetOrThrow(): ResponseEntity<AssetResponseMessage> {
val response = getOrThrow(controller.issueAsset(ASSET_REQUEST_MESSAGE))
return try {
response as ResponseEntity<AssetResponseMessage>
} catch (classCastException: ClassCastException) {
val errorResponse = response as ResponseEntity<ErrorResponseMessage>
fail(errorResponse.body.error)
}
}
In the event of a successful response, getOrThrow(controller.issueAsset(ASSET_REQUEST_MESSAGE))
will return ResponseEntity<AssetResponseMessage>
.
In the event of an unsuccessful response it will return ResponseEntity<ErrorResponseMessage>
, unless there is some catastrophic failure, in which case it throws an exception.
Since the generic part of the response is unknown at this point, the function should first try
to cast the response to ResponseEntity<AssetResponseMessage>
.
If it can't perform this cast, it will throw a ClassCastException
and then tries to cast the response to ResponseEntity<ErrorResponseMessage>
.
It should then extract the error message and fail
with this message, throwing an AssertionError
The problem is that I actually get this output
java.lang.ClassCastException: com.demo.api.messages.ErrorResponseMessage cannot be cast to com.demo.api.messages.AssetResponseMessage
It looks like catch(classCastException: ClassCastException)
gets ignored completely! Why is this?
Thanks to lrcover for suggesting as?
I have now come up with this as a solution
private fun <TResult> responseOrFail(response: Any): ResponseEntity<TResult> {
val errorResponse = response as? ResponseEntity<ErrorResponseMessage>
if (errorResponse != null) {
fail(errorResponse.body.error)
}
return response as ResponseEntity<TResult>
}
Then in my method:
return responseOrFail(response)
And now I have the desired result.