Diga adeus ao try/catch. Use to() no seu código assíncrono.

Se você já se pegou escrevendo vários blocos try/catch
em código assíncrono, sabe como isso rapidamente vira um caos. Felizmente, existe uma abordagem mais elegante para tratar erros em Promises: a função to()
.
Hoje vou te mostrar como usar essa função simples para deixar seu código limpo, funcional e mais legível. Ideal para APIs, fetch e qualquer Promise que possa falhar.
O problema com try/catch
em Promises
async function carregarUsuario() {
try {
const res = await fetch('/api/user');
const json = await res.json();
console.log(json);
} catch (err) {
console.error('Erro ao buscar usuário:', err);
}
}
Esse padrão é funcional, mas se você tiver mais de uma Promise, vai precisar de try/catch aninhado ou separar demais a lógica. Fica verboso, difícil de manter e de testar.
A função to()
export async function to<T>(promise: Promise<T>): Promise<[Error | null, T | null]> {
try {
const data = await promise;
return [null, data];
} catch (err) {
return [err as Error, null];
}
}
Simples: ela embrulha uma Promise e sempre retorna um array com [erro, resultado]
.
Exemplo com fetch
import { to } from './utils/to';
async function buscarProduto(id: string) {
const [errRes, res] = await to(fetch(`/api/produtos/${id}`));
if (errRes) return console.error('Erro de rede:', errRes);
const [errJson, data] = await to(res!.json());
if (errJson) return console.error('Erro no JSON:', errJson);
console.log('Produto carregado:', data);
}
Sem try
, sem catch
, e a lógica continua fluindo. O código fica mais funcional e fácil de testar por partes.
Vantagens
- ✅ Sem repetição de
try/catch
- ✅ Padroniza o tratamento de erro
- ✅ Ideal para múltiplas Promises em sequência
- ✅ Fica mais legível e com menos indentação
Crie um hook customizado
Se estiver em um projeto React, pode até criar um hook com to()
para chamadas API:
export function useSafeFetch<T>() {
return async (url: string): Promise<[Error | null, T | null]> => {
const [err, res] = await to(fetch(url));
if (err) return [err, null];
const [parseErr, data] = await to<T>(res!.json());
return [parseErr, data];
};
}
A função to()
não é mágica — ela é apenas uma forma inteligente de estruturar código assíncrono de forma limpa e previsível. Você pode usá-la em qualquer projeto Node, React, Next.js ou qualquer app com Promises.
Adote esse padrão e nunca mais sofra com blocos infinitos de try/catch
.