Executando verificação de segurança...
1

Chega de Try/Catch aninhado: Transformei um padrão repetitivo em um pacote NPM (promise-tuple)

Recentemente, percebi que em quase todos os meus projetos eu acabava escrevendo o mesmo utilitário para lidar com Promises.
Decidi que era hora de parar de copiar e colar código e publiquei um pacote npm: o promise-tuple.

A Motivação

Sabe quando você precisa executar várias chamadas assíncronas em sequência, mas cada uma delas exige um tratamento de erro específico? O padrão tradicional com try/catch costuma resultar em um código "escadinha" ou em diversas variáveis declaradas com let fora do bloco para que possam ser acessadas depois.

Exemplo do "problema":

let user;
try {
  user = await fetchUser();
} catch (err) {
  return handleUserError(err);
}

let posts;
try {
  posts = await fetchPosts(user.id);
} catch (err) {
  return handlePostError(err);
}

A Solução: Padrão Tupla

Inspirado em linguagens como Go, a ideia é retornar sempre uma tupla (array fixo) contendo [data, error]. Se o erro existir, ele vem preenchido; caso contrário, você tem seus dados.

Com o promise-tuple, o código acima fica assim:

import promiseTuple from 'promise-tuple';

const [user, userErr] = await promiseTuple(fetchUser());
if (userErr) return handleUserError(userErr);

const [posts, postsErr] = await promiseTuple(fetchPosts(user.id));
if (postsErr) return handlePostError(postsErr);

Por que usar?

  • Legibilidade: O fluxo de erro fica explícito e colado à chamada da função.
  • TypeScript Nativo: O pacote foi escrito pensando em inferência de tipos, então o data e o error são tipados corretamente.
  • Minimalista: Sem dependências externas e extremamente leve.

Conclusão

Eu sei que existem outras 'libs' que fazem coisas similares, mas criar a minha própria me permitiu ajustar exatamente ao que eu precisava e, de quebra, contribuir com a comunidade.

Link do pacote npm: https://www.npmjs.com/package/promise-tuple

Carregando publicação patrocinada...
2

Nos exemplos que citou:

const user = await fetchUser().catch(handleUserError);
if (!user) return;

Tem custo zero, porque usar tem pacote?

1

obrigado pela contribuição

realmente a sua sugestão faz a mesma coisa sem a necessidade de adicionar um pacote adicional ao projeto

o pacote que criei fica como opção apenas por preferências na escrita de código

eu mesmo, quando tiver a necessidade de usar poucas vezes, irei optar pelo seu código