Relançamento e encadeamento de exceções
Relance exceções seletivamente e envolva erros de baixo nível, encadeando suas causas.
Relançamento e encadeamento de exceções é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 4 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.
Relançando e encapsulando
Às vezes, você captura uma exceção apenas para fazer log, encapsulá-la ou convertê-la antes de permitir que uma exceção mais específica se propague. O Kotlin torna isso idiomático.
Relançamento simples
Para relançar, basta usar throw e novamente — a propagação continua até o próximo manipulador.
fun main() {
try {
try { "x".toInt() }
catch (e: NumberFormatException) {
println("logging: ${e.message}")
throw e // re-throw original
}
} catch (e: NumberFormatException) {
println("outer caught: ${e.message}")
}
}Encapsulamento com uma exceção personalizada
Passe a exceção original como cause ao construir uma nova, para preservar a cadeia.
class ParseException(msg: String, cause: Throwable) : RuntimeException(msg, cause)
fun main() {
try {
try { "xyz".toInt() }
catch (e: NumberFormatException) {
throw ParseException("could not parse user input", e)
}
} catch (e: ParseException) {
println("got: ${e.message}")
println("cause: ${e.cause?.message}")
}
}Inspecionando a cadeia de causas
A propriedade cause aponta para a exceção anterior. Percorra-a para imprimir a causa raiz completa.
fun main() {
val e = RuntimeException("top",
RuntimeException("middle",
RuntimeException("root")))
var current: Throwable? = e
while (current != null) {
println(current.message)
current = current.cause
}
}Relançamento seletivo
Capture um tipo amplo e depois relance-o se NOT corresponder ao caso esperado.
fun parseRequired(s: String): Int {
try {
return s.toInt()
} catch (e: NumberFormatException) {
if (s.isBlank()) return 0
throw e // unexpected — let it propagate
}
}
fun main() {
println(parseRequired("42"))
println(parseRequired(""))
// parseRequired("abc") // throws
}Adicionando contexto
Encapsule com uma exceção de domínio para adicionar o contexto que faltava à original — entrada, identificador da requisição etc.
class UploadError(msg: String, cause: Throwable) : RuntimeException(msg, cause)
fun upload(file: String) {
try { throw RuntimeException("disk full") }
catch (e: Throwable) { throw UploadError("uploading $file failed", e) }
}
fun main() {
try { upload("photo.jpg") }
catch (e: UploadError) { println("${e.message} <- ${e.cause?.message}") }
}Não perca o rastreamento da pilha
Ao encapsular, sempre passe a exceção original como cause — nunca crie apenas uma nova exceção com a mesma mensagem, mas sem causa. O rastreamento da pilha é seu recurso essencial para depuração.
class Wrapped(m: String, cause: Throwable) : RuntimeException(m, cause)
fun main() {
try {
try { error("inner") }
catch (e: Throwable) { throw Wrapped("outer", e) }
} catch (e: Wrapped) {
println("message: ${e.message}")
println("cause: ${e.cause?.message}")
}
}Relance sem encapsular
Se tudo de que precisa é fazer log, basta usar throw e depois da chamada de log — não é necessário encapsular.
fun risky() {
try { throw IllegalStateException("oops") }
catch (e: IllegalStateException) {
println("Logging before rethrow: ${e.message}")
throw e
}
}
fun main() {
try { risky() }
catch (e: IllegalStateException) { println("outer: ${e.message}") }
}finally para limpeza durante o relançamento
Use finally para limpar os recursos mesmo ao relançar uma exceção.
fun process() {
try {
throw RuntimeException("failure")
} finally {
println("cleanup ran")
}
}
fun main() {
try { process() }
catch (e: RuntimeException) { println("caught: ${e.message}") }
}Exceções suprimidas
Se o próprio finally lançar uma exceção, a exceção original será suprimida por padrão. Use addSuppressed para preservar ambas.
fun main() {
val primary = RuntimeException("primary")
val secondary = RuntimeException("from cleanup")
primary.addSuppressed(secondary)
println(primary.suppressed.joinToString { it.message ?: "?" })
}Antipadrão: engolir e depois lançar uma diferente
Capturar uma exceção e lançar outra, sem relação com ela e sem causa, destrói informações importantes para a depuração. Sempre informe cause.
// BAD
// catch (e: IOException) { throw RuntimeException("error") }
// GOOD
// catch (e: IOException) { throw RuntimeException("error reading config", e) }
fun main() { println("Pass cause when re-throwing!") }Verificação rápida
Ao encapsular uma exceção em uma nova, o que deve fazer para preservar o rastreamento de pilha original?
Recapitulação
Para lançar novamente: throw e. Para encapsular: lance uma nova exceção com cause = e. Preserve sempre a cadeia de causas — nunca crie um encapsulador sem causa. Use finally para a limpeza e addSuppressed quando a própria limpeza falhar.
Perguntas Frequentes
A aula “Relançamento e encadeamento de exceções” é grátis?
Sim — o texto completo de “Relançamento e encadeamento de 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 “Relançamento e encadeamento de exceções”?
Relance exceções seletivamente e envolva erros de baixo nível, encadeando suas causas. 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 4 de 4.
Quanto tempo leva a aula “Relançamento e encadeamento de 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
- try/catch/finally como expressão
- Criando classes de exceção personalizadas
- runCatching e Result
- Relançamento e encadeamento de exceções