0Pricing
Kotlin Academy · Aula

Criando classes de exceção personalizadas

Defina exceções específicas do domínio com mensagens e propriedades significativas.

Criando classes de exceção personalizadas é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 2 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.

Por que usar exceções personalizadas?

As exceções personalizadas codificam o significado do domínio: os chamadores podem capturá-las especificamente, obter mensagens úteis e agir de modo diferente com base no tipo.

A exceção personalizada mais simples

Crie uma subclasse de Exception — ou de uma subclasse específica, como RuntimeException — e passe uma mensagem ao construtor da superclasse.

class InvalidEmailException(message: String) : Exception(message)
fun main() {
    try {
        throw InvalidEmailException("missing @")
    } catch (e: InvalidEmailException) {
        println("caught: ${e.message}")
    }
}

Exceção com propriedades

Adicione campos para transmitir contexto: status HTTP, nome do campo, contagem de tentativas etc.

class HttpError(
    message: String,
    val statusCode: Int
) : Exception(message)
fun main() {
    try {
        throw HttpError("Not Found", 404)
    } catch (e: HttpError) {
        println("HTTP ${e.statusCode}: ${e.message}")
    }
}

Exceção com causa

Passe uma cause para preservar a exceção original na cadeia.

class DatabaseError(message: String, cause: Throwable) : Exception(message, cause)
fun main() {
    try {
        try { error("connection refused") }
        catch (e: Throwable) { throw DatabaseError("query failed", e) }
    } catch (e: DatabaseError) {
        println("${e.message} (caused by: ${e.cause?.message})")
    }
}

Exceções verificadas versus não verificadas

O Kotlin trata todas as exceções como não verificadas (nenhuma declaração throws é necessária). Por convenção, crie subclasses de RuntimeException.

class ValidationException(field: String, message: String) :
    RuntimeException("[$field] $message")
fun main() {
    try {
        throw ValidationException("age", "must be positive")
    } catch (e: ValidationException) {
        println(e.message)
    }
}

Hierarquia de exceções do domínio

Crie uma hierarquia para que os chamadores possam capturar um tipo base para tratamento geral ou subtipos específicos para casos especiais.

open class AppException(message: String) : RuntimeException(message)
class NotFoundException(what: String) : AppException("$what not found")
class UnauthorizedException : AppException("not authorized")
fun main() {
    val errors = listOf(NotFoundException("user"), UnauthorizedException())
    for (e in errors) {
        try { throw e }
        catch (e: AppException) { println("App error: ${e.message}") }
    }
}

Hierarquia selada de exceções

Para conjuntos fechados de tipos de erro, use uma hierarquia sealed — os chamadores podem tratar exaustivamente cada variante.

sealed class ApiError(message: String) : RuntimeException(message) {
    class Timeout : ApiError("timeout")
    class NotFound(val id: String) : ApiError("not found: $id")
    class ServerError(val status: Int) : ApiError("server returned $status")
}
fun describe(e: ApiError) = when (e) {
    is ApiError.Timeout -> "request timed out"
    is ApiError.NotFound -> "id ${e.id} missing"
    is ApiError.ServerError -> "5xx: ${e.status}"
}
fun main() {
    println(describe(ApiError.NotFound("user-42")))
}

Convenção de nomenclatura

Termine os nomes de classes de exceção personalizadas com Exception ou Error para manter a clareza. Use o passado ou um substantivo (por exemplo, NotFound, InvalidInput).

class InvalidInputException(msg: String) : RuntimeException(msg)
class UserNotFoundException(id: Int) : RuntimeException("user $id not found")
fun main() {
    try { throw UserNotFoundException(7) }
    catch (e: UserNotFoundException) { println(e.message) }
}

Documentando exceções

Use o KDoc @throws para documentar quais exceções uma função pode lançar.

/**
 * @throws InvalidEmailException if the email is malformed
 */
fun validate(email: String) {
    if ("@" !in email) throw InvalidEmailException("missing @")
}
class InvalidEmailException(m: String) : RuntimeException(m)
fun main() {
    try { validate("nope") }
    catch (e: InvalidEmailException) { println(e.message) }
}

Evite usar exceções em excesso

Exceções são para situações excepcionais. Para resultados esperados — entrada vazia ou campo opcional ausente — prefira retornos anuláveis, tipos de resultado selados ou valores padrão.

fun findUser(id: Int): String? = if (id == 1) "Alice" else null
fun main() {
    val name = findUser(42) ?: "(unknown)"
    println(name) // (unknown), no exception
}

Exemplo prático

Uma exceção personalizada realista para um cliente de API fictício, com status e corpo.

class ApiException(
    message: String,
    val statusCode: Int,
    val responseBody: String
) : RuntimeException(message)
fun main() {
    try {
        throw ApiException("Bad Request", 400, "{\"error\":\"invalid\"}")
    } catch (e: ApiException) {
        println("[${e.statusCode}] ${e.message}: ${e.responseBody}")
    }
}

Verificação rápida

Qual classe pai é usada com mais frequência ao definir uma exceção Kotlin específica do domínio?

Recapitulação

Exceções personalizadas codificam o significado do domínio. Crie subclasses de RuntimeException ou Exception; adicione propriedades para fornecer contexto; preserve as causas; crie hierarquias para capturas agrupadas. Use exceções seladas para conjuntos fechados e prefira tipos anuláveis ou de resultado quando os erros forem esperados.

Perguntas Frequentes

A aula “Criando classes de exceção personalizadas” é grátis?

Sim — o texto completo de “Criando classes de exceção personalizadas” é 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 “Criando classes de exceção personalizadas”?

Defina exceções específicas do domínio com mensagens e propriedades significativas. 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 2 de 4.

Quanto tempo leva a aula “Criando classes de exceção personalizadas”?

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

  1. try/catch/finally como expressão
  2. Criando classes de exceção personalizadas
  3. runCatching e Result
  4. Relançamento e encadeamento de exceções
← Voltar para Kotlin Academy