---
title: "Catch em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/catch-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/catch-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda o operador catch em Zig: capture e trate erros de error unions com valor de fallback ou lógica customizada. Guia completo em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Catch em Zig — O que é e Como Usar

Entenda o operador catch em Zig: capture e trate erros de error unions com valor de fallback ou lógica customizada. Guia completo em pt-BR.


# Catch em Zig — O que é e Como Usar

## Definição

O operador **`catch`** em Zig é usado para **capturar e tratar erros** de [error unions](/glossario/error-union/) (`ErrorSet!T`). Ele fornece um mecanismo para reagir quando uma operação falha, seja fornecendo um valor de fallback, executando lógica de recuperação ou propagando o erro de forma diferente.

A sintaxe básica é: `error_union catch fallback` ou `error_union catch |err| { ... }`.

## Por que Catch Importa

1. **Tratamento local de erros**: Permite lidar com o erro no ponto exato onde ele ocorre.
2. **Valores de fallback**: Fornece alternativas quando operações falham.
3. **Captura do erro**: Permite inspecionar qual erro ocorreu para tomar decisões.
4. **Complementa `try`**: Enquanto `try` propaga, `catch` trata.

## Exemplo Prático

### Catch com Valor de Fallback

```zig
const std = @import("std");

fn parsearNumero(texto: []const u8) !u32 {
    return std.fmt.parseInt(u32, texto, 10);
}

pub fn main() void {
    // Se falhar, usa 0 como padrão
    const valor = parsearNumero("42") catch 0;
    std.debug.print("Valor: {}\n", .{valor}); // 42

    const invalido = parsearNumero("abc") catch 0;
    std.debug.print("Inválido: {}\n", .{invalido}); // 0
}
```

### Catch com Captura de Erro

```zig
const std = @import("std");

fn abrirArquivo(caminho: []const u8) !std.fs.File {
    return std.fs.cwd().openFile(caminho, .{});
}

pub fn main() void {
    const arquivo = abrirArquivo("config.txt") catch |err| {
        switch (err) {
            error.FileNotFound => {
                std.debug.print("Arquivo não encontrado, usando padrões\n", .{});
                return;
            },
            error.AccessDenied => {
                std.debug.print("Permissão negada\n", .{});
                return;
            },
            else => {
                std.debug.print("Erro inesperado: {}\n", .{err});
                return;
            },
        }
    };
    defer arquivo.close();

    std.debug.print("Arquivo aberto com sucesso\n", .{});
}
```

### Catch com Bloco e Lógica

```zig
const porta = parsearNumero(config.porta_texto) catch blk: {
    std.log.warn("Porta inválida, usando 8080", .{});
    metricas.incrementar("config_fallback");
    break :blk 8080;
};
```

### Catch vs Try

```zig
fn processar() !void {
    // try: propaga o erro para o chamador
    const a = try operacao1();

    // catch: trata o erro localmente
    const b = operacao2() catch |err| {
        std.log.err("operacao2 falhou: {}", .{err});
        return err; // Pode re-propagar manualmente
    };

    _ = a;
    _ = b;
}
```

### Catch com Unreachable

```zig
// Quando sabemos que o erro é impossível
const valor: u32 = std.fmt.parseInt(u32, "42", 10) catch unreachable;
```

### Padrão: Logging + Fallback

```zig
fn obterConfiguracao() Config {
    return lerConfigDoArquivo() catch |err| {
        std.log.warn("Falha ao ler config ({s}), usando padrão", .{@errorName(err)});
        return Config.padrao();
    };
}
```

## Catch vs Orelse

| Operador | Funciona com | Trata |
|----------|-------------|-------|
| `catch` | `!T` (error union) | Erros |
| `orelse` | `?T` (optional) | null |

```zig
// catch para error unions
const a: anyerror!u32 = error.Falha;
const val_a = a catch 0;

// orelse para optionals
const b: ?u32 = null;
const val_b = b orelse 0;
```

## Armadilhas Comuns

- **Usar `catch` com optional**: `catch` funciona apenas com error unions (`!T`). Para optionals (`?T`), use `orelse`.
- **Catch com unreachable irresponsável**: Se o erro realmente ocorrer em Release, é comportamento indefinido. Use apenas quando tiver certeza.
- **Engolir erros silenciosamente**: `operacao() catch {}` ignora o erro sem tratamento. Pelo menos registre um log.
- **Não usar a informação do erro**: Quando possível, capture o erro com `catch |err|` para logging ou decisões.

## Boas Práticas com Catch

O uso adequado de `catch` melhora a robustez e legibilidade do código. Algumas recomendações:

**1. Prefira `catch |err|` a `catch` simples**: Capturar o erro permite logging e diagnóstico mais detalhado.

**2. Evite engolir erros**: `operacao() catch {}` é tentador, mas silencia problemas reais. Pelo menos registre o erro:

```zig
operacao() catch |err| {
    std.log.warn("operacao falhou: {s}", .{@errorName(err)});
};
```

**3. Use `catch unreachable` com critério**: É seguro apenas quando a análise lógica do código garante que o erro é impossível naquele ponto. Em `ReleaseFast`, isso vira comportamento indefinido se você estiver errado.

**4. Combine `catch` com métricas**: Em serviços de produção, o bloco `catch` é o lugar certo para incrementar contadores de erro antes de retornar um fallback.

```zig
const config = lerConfig() catch |err| blk: {
    metricas.contarErro("config_load", err);
    std.log.err("Config falhou ({s}), usando padrão", .{@errorName(err)});
    break :blk Config.padrao();
};
```

## Comparação com Outras Linguagens

Em linguagens com exceções (Java, C++, Python), o equivalente seria `try/catch`. A diferença fundamental é que em Zig os erros são valores no sistema de tipos — não há overhead de stack unwinding, e o compilador pode garantir que todos os erros são tratados. Em Rust, o equivalente é o método `.unwrap_or()` e o operador `?` (semelhante ao `try` do Zig). A vantagem do `catch` do Zig sobre o `match` do Rust é a sintaxe mais concisa para o caso comum de fornecer um valor de fallback.

## Termos Relacionados

- [Error Union](/glossario/error-union/) — Tipo que pode conter erro ou valor
- [Try](/glossario/try/) — Propagação automática de erros
- [Orelse](/glossario/orelse/) — Equivalente para optionals
- [Error Set](/glossario/error-set/) — Conjuntos de erros nomeados
- [Errdefer](/glossario/errdefer/) — Limpeza condicional em caso de erro

## Tutoriais Relacionados

- [Tratamento de Erros em Zig](/tutoriais/tratamento-de-erros-em-zig/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
