Either<L, R>: tratamento de erros tipado sem exceções
Use Either para representar sucesso e falha sem lançar exceções.
Either<L, R>: tratamento de erros tipado sem exceções é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.
O problema de usar exceções para a lógica de negócio
As exceções são projetadas para falhas inesperadas (ponteiro nulo, erro de IO). Usá-las para sinalizar falhas de negócio esperadas (falha de validação, "não encontrado") torna o fluxo de controle invisível, força o uso de try/catch em todos os pontos de chamada e oculta os erros nas assinaturas das funções.
O que é Either<L, R>?
Either é um tipo soma com dois casos: Left(value: L) normalmente contém o erro, e Right(value: R) normalmente contém o valor de sucesso. Uma função que retorna Either torna explícita em sua assinatura a possibilidade de falha.
Either do Arrow
Adicione o Arrow ao seu projeto para obter Either e todo o seu ecossistema de operadores:
// build.gradle.kts
implementation("io.arrow-kt:arrow-core:1.2.4")
// Usage
import arrow.core.Either
import arrow.core.left
import arrow.core.rightRetornando Either de uma função
Retorne value.right() em caso de sucesso e error.left() em caso de falha. O chamador precisa tratar ambos os ramos:
sealed class UserError { object NotFound : UserError(); data class InvalidEmail(val msg: String) : UserError() }
fun findUser(id: Long): Either<UserError, User> =
if (id <= 0) UserError.NotFound.left()
else User(id, "Alice").right()Consumindo Either com fold
Use fold(ifLeft, ifRight) para tratar ambos os casos em uma única expressão:
val result = findUser(1L)
val message = result.fold(
ifLeft = { error -> "Error: $error" },
ifRight = { user -> "Found: ${user.name}" }
)
println(message)Transformando o valor Right com map
map { } transforma o valor Right sem alterar um Left. Isso torna Either um funtor — você pode encadear transformações com segurança:
val nameResult: Either<UserError, String> = findUser(1L).map { it.name }Encadeando com flatMap
flatMap { } encadeia cálculos que também retornam Either. Se qualquer etapa retornar Left, o encadeamento é interrompido e o erro é propagado sem executar as etapas seguintes:
fun validateEmail(email: String): Either<UserError, String> =
if (email.contains("@")) email.right()
else UserError.InvalidEmail("bad format").left()
fun createUser(email: String): Either<UserError, User> =
validateEmail(email).flatMap { validEmail ->
User(1L, validEmail).right()
}Either.catch para encapsular exceções
Either.catch { } executa um bloco e encapsula qualquer exceção como um Left. Use-o na fronteira entre código legado que lança exceções e seu domínio baseado em Either:
val result: Either<Throwable, User> = Either.catch {
userRepository.findOrThrow(id)
}Recuperando com getOrElse e orElse
getOrElse { default } extrai o valor Right ou retorna um valor padrão. orElse { alternativeEither } substitui um Left por outro cálculo:
val user: User = findUser(0L).getOrElse { User(-1L, "Guest") }
val user2: Either<UserError, User> = findUser(0L).orElse { User(99L, "Default").right() }Correspondência de padrões com when
Use when em uma classe selada semelhante a Either ou no próprio Either, usando is Either.Left / Either.Right, para tratar todos os casos de forma exaustiva:
when (val r = findUser(1L)) {
is Either.Left -> println("Error: ${r.value}")
is Either.Right -> println("User: ${r.value.name}")
}Either nas camadas de serviço
Retorne Either pelas funções do repositório e do serviço. Mapeie-o para respostas HTTP no nível da rota Ktor, mantendo a lógica de negócio livre de preocupações relacionadas ao arcabouço:
get("/users/{id}") {
val id = call.parameters["id"]?.toLongOrNull() ?: return@get call.respond(HttpStatusCode.BadRequest)
userService.findById(id).fold(
ifLeft = { call.respond(HttpStatusCode.NotFound) },
ifRight = { call.respond(it) }
)
}Verificação rápida
O que flatMap { } faz com um valor Either.Left?
Recapitulação: Either<L, R>
Principais conclusões:
Eithertorna o caminho de falha explícito na assinatura da funçãoRight= sucesso;Left= falha (por convenção)map { }— transformar o valor de sucesso;flatMap { }— encadear cálculos que podem falharfold(ifLeft, ifRight)— consumir ambos os casos em uma única expressãoEither.catch { }— encapsular código que lança exceções nas fronteiras
Perguntas Frequentes
A aula “Either<L, R>: tratamento de erros tipado sem exceções” é grátis?
Sim — o texto completo de “Either<L, R>: tratamento de erros tipado sem exceções” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.
O que vou aprender em “Either<L, R>: tratamento de erros tipado sem exceções”?
Use Either para representar sucesso e falha sem lançar exceções. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Kotlin Academy?
Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Either<L, R>: tratamento de erros tipado sem exceções”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Kotlin Academy?
Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Either : tratamento de erros tipado sem exceções
- DSL Raise do Arrow: composição de erros tipados
- Option e Nullable: quando usar cada um
- Modelagem funcional de domínios com os tipos centrais do Arrow