Lição 4: Falhas como parte do contrato

Uma falha de rede, uma conta desativada e um arquivo ausente são resultados possíveis do domínio. O tipo Result torna esses caminhos visíveis na assinatura, em vez de escondê-los numa exceção.

Objetivo

Em uma frase: retornar e propagar erros de forma explícita e escaneável.

Código

func buscarSaldo(conta: ref Conta): Result<int, str> {
    if conta.ativa == false {
        return Result.Err("conta desativada")
    }
    return Result.Ok(conta.saldo)
}

O tipo Result<int, str> diz que a função ou devolve um int (Result.Ok(...)) ou devolve uma mensagem de erro (Result.Err(...)). Nada de exceção escondida nos bastidores.

Propagando com ?

func resumo(conta: ref Conta): Result<str, str> {
    let saldo = buscarSaldo(conta)?
    return Result.Ok("Saldo: " + saldo)
}

O ? encurta a propagação: se der Err, a função inteira retorna esse erro; se der Ok, você extrai o valor.

Experimente

Remova o ? de buscarSaldo(conta) e veja o compilador pedir que você trate o Result explicitamente. Ele não deixa um erro escapar sem você decidir o que fazer.

Dica

Option<T> funciona do mesmo jeito: Option.Some(...) ou Option.None, sem null. Combine Option e Result para modelar “pode não existir” e “pode falhar” como coisas distintas.

Erros como valores mantêm o fluxo de erro visível no próprio código — você vê exatamente onde uma operação pode falhar e qual camada decide o que fazer.