---
title: "Try in Non-Error Function — Como Resolver em Zig"
url: "https://ziglang.com.br/erros/try-in-non-error-function-como-resolver-em-zig/"
markdown_url: "https://ziglang.com.br/erros/try-in-non-error-function-como-resolver-em-zig.MD"
description: "Entenda o erro de usar 'try' em uma função que não retorna error union em Zig. Veja como ajustar a assinatura da função ou tratar o erro localmente."
date: "2026-02-21"
author: "Zig Brasil"
---

# Try in Non-Error Function — Como Resolver em Zig

Entenda o erro de usar 'try' em uma função que não retorna error union em Zig. Veja como ajustar a assinatura da função ou tratar o erro localmente.


# Try in Non-Error Function — Como Resolver em Zig

## O Que Este Erro Significa

O erro de compilação ocorre quando você usa a palavra-chave `try` dentro de uma função cujo tipo de retorno não é um error union. O operador `try` em Zig serve para propagar erros automaticamente — se a expressão resultar em erro, `try` retorna esse erro da função atual. Para isso funcionar, a função precisa ter um tipo de retorno que suporte erros (como `!void`, `!u32`, `anyerror!T`, etc.).

A mensagem do compilador:

```
error: expected type 'error union', found 'void'
note: cannot convert error union to non-error-union type
```

Ou:

```
error: 'try' is not allowed in function with return type 'void'
```

## Causas Comuns

### 1. main() sem Tipo de Retorno de Erro

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

pub fn main() void {  // void — não pode propagar erros
    const file = try std.fs.cwd().openFile("dados.txt", .{});
    // ERRO DE COMPILAÇÃO: 'try' em função void
    defer file.close();
}
```

### 2. Callback sem Tipo de Retorno de Erro

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

fn meuCallback(item: u32) void {  // void — não aceita try
    const dados = try obterDados(item);
    // ERRO: try em função que retorna void
    _ = dados;
}

fn obterDados(id: u32) ![]u8 {
    _ = id;
    return error.NaoEncontrado;
}
```

### 3. Função de Comparação

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

fn comparar(a: []const u8, b: []const u8) bool {
    const va = try std.fmt.parseInt(i32, a, 10);
    // ERRO: try em função que retorna bool
    const vb = try std.fmt.parseInt(i32, b, 10);
    return va < vb;
    _ = vb;
}
```

### 4. Método que Não Declara Erro no Retorno

```zig
const Processador = struct {
    fn processar(self: *Processador) void {  // void
        const resultado = try self.carregar();
        // ERRO: try em função void
        _ = resultado;
    }

    fn carregar(self: *Processador) ![]u8 {
        _ = self;
        return error.Falha;
    }
};
```

## Como Corrigir

### Solucao 1: Mudar o Tipo de Retorno para Error Union

A solução mais simples é permitir que a função propague erros:

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

pub fn main() !void {  // Mudou de void para !void
    const file = try std.fs.cwd().openFile("dados.txt", .{});
    defer file.close();
    // Agora try funciona corretamente
}
```

### Solucao 2: Usar catch ao Invés de try

Se a função não pode mudar seu tipo de retorno, trate o erro localmente:

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

pub fn main() void {
    const file = std.fs.cwd().openFile("dados.txt", .{}) catch |err| {
        std.debug.print("Erro ao abrir arquivo: {}\n", .{err});
        return;
    };
    defer file.close();
    _ = file;
}
```

### Solucao 3: catch com Valor Padrão

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

fn comparar(context: void, a: []const u8, b: []const u8) bool {
    _ = context;
    const va = std.fmt.parseInt(i32, a, 10) catch return false;
    const vb = std.fmt.parseInt(i32, b, 10) catch return false;
    return va < vb;
}
```

### Solucao 4: catch unreachable (Quando o Erro é Impossível)

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

fn formatarNumero(valor: u32) void {
    var buf: [20]u8 = undefined;
    // bufPrint com u32 nunca falha quando o buffer é grande o suficiente
    const resultado = std.fmt.bufPrint(&buf, "{d}", .{valor}) catch unreachable;
    std.debug.print("{s}\n", .{resultado});
}
```

### Solucao 5: Encapsular em Função que Retorna Erro

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

fn meuCallbackInterno() !void {
    const dados = try obterDados(42);
    _ = dados;
}

fn meuCallback() void {
    meuCallbackInterno() catch |err| {
        std.debug.print("Erro no callback: {}\n", .{err});
    };
}

fn obterDados(id: u32) ![]u8 {
    _ = id;
    return error.NaoEncontrado;
}
```

### Solucao 6: Usar if com Error Union

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

fn processar(caminho: []const u8) void {
    if (std.fs.cwd().openFile(caminho, .{})) |file| {
        defer file.close();
        // Processa o arquivo
        _ = file;
    } else |err| {
        std.debug.print("Falha: {}\n", .{err});
    }
}
```

## Quando Usar Cada Abordagem

| Situação | Abordagem Recomendada |
|----------|----------------------|
| Função pode falhar | Mudar retorno para `!T` + usar `try` |
| Callback com assinatura fixa | Usar `catch` localmente |
| Erro é impossível | `catch unreachable` (com cuidado) |
| Precisa de valor padrão | `catch valor_padrao` |
| Precisa log de erro | `catch \|err\|` com bloco |

## Entendendo try vs catch

```zig
// try é açúcar sintático para:
const valor = try expressao;
// Equivale a:
const valor = expressao catch |err| return err;

// Portanto, try PRECISA que a função possa retornar erro
// Se não pode retornar erro, use catch diretamente
```

## Padrão Comum: main com !void

Em Zig, é idiomático declarar `main` como `!void` para poder usar `try`:

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

pub fn main() !void {
    // Agora podemos usar try livremente
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const dados = try allocator.alloc(u8, 1024);
    defer allocator.free(dados);

    const file = try std.fs.cwd().openFile("config.txt", .{});
    defer file.close();

    const bytes = try file.readAll(dados);
    std.debug.print("Lidos {} bytes\n", .{bytes});
}
```

## Erros Relacionados

- [Error not handled](/erros/erro-error-not-handled/) — Erro não tratado
- [Catch reached unreachable](/erros/erro-catch-unreachable/) — Catch atingiu unreachable
- [Expected return](/erros/erro-expected-return/) — Retorno esperado
- [Attempt to unwrap error](/erros/erro-unwrap-error/) — Tentativa de desempacotar error

## Links Úteis

- [Documentação oficial do Zig — try](https://ziglang.org/documentation/master/#try)
- [Documentação oficial do Zig — Error Union](https://ziglang.org/documentation/master/#Error-Union-Type)
- [Receitas de tratamento de erros](/receitas/)
- [Tutorial sobre error unions](/tutoriais/)
