Home > Software engineering >  How to handle a forEach loop that returns early based on an enum except for one path in Kotlin
How to handle a forEach loop that returns early based on an enum except for one path in Kotlin

Time:09-02

We have an API service call that returns a bunch of validation messages. In each message there is a string that contains an error code.

Our implementation converts the validation string into an enum value and then we process the enumeration as there are some error code we just don't care about.

The question becomes, how to handle the loop of messages in a Kotlin way:

response.validationErrors?.forEach {
    val mediaFailure = decodeValidationMessage(it.message)

    if (mediaFailure != MediaFailure.Unknown) {
        return when (mediaFailure) {
            MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
            MediaFailure.NotSupported -> Response.validationFailed()
            MediaFailure.InternalError -> Response.serviceFailed()
            else -> throw NotImplementedError()
        }
    }
}

Here we loop through all the messages, then once the message error is not "Unknown" it returns the necessary response to the caller.

However, IntelliJ wants the else path, even though the if prevents that from happening.

Is there a proper Kotlin way of implementing this kind of loop?

CodePudding user response:

From what I understood, you want to return a response for the first mediaFailure which is not MediaFailure.Unknown and you don't want that throw NotImplementedError() part in your function. One way to fix this is to remove the if condition and continue the forEach loop when MediaFailure.Unknown is found.

response.validationErrors?.forEach {
    val mediaFailure = decodeValidationMessage(it.message)

    return when (mediaFailure) {
        MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
        MediaFailure.NotSupported -> Response.validationFailed()
        MediaFailure.InternalError -> Response.serviceFailed()
        MediaFailure.Unknown -> return@forEach // continue the loop
    }
}
  • Related