Pesquisa de site

typescript - Como tipar erros do Firebase JS SDK em blocos try-catch?


Dada essa função que salva documentos no Firestore, estou tentando definir o tipo do objeto err.

async function saveToFirestore(obj: SOME_OBJECT, collection: string, docId: string) {
  try {
    await firebase.firestore().collection(collection).doc(docId).set(obj);
  }
  catch(err: firebase.firestore.FirestoreError) {
    // THIS DOESN'T SEEM TO BE POSSIBLE
  }
}

Também tentei com firebase.FirebaseError

Estou recebendo este erro:

O que estou procurando é uma maneira de obter conclusão automática no objeto de erro que vem do Firebase. Como as pessoas geralmente lidam com isso? O objeto error deve sempre ser tipado como any ou unknown? Por quê?


ATUALIZAÇÃO

Dado o fato de que não é possível digitar o catch(err) diretamente, meu objetivo era ter algo assim:

catch(err) {
  if (err instanceof firebase.FirebaseError) {  // <--- THIS DOES NOT WORK
    throw `something for the FirebaseError`
  }
  else {
    throw `something else for other error types`
  }
}

Mas a partir da discussão sobre o problema que Frank apontou em sua resposta, parece que isso não é possível.

_Não permitimos anotações de tipo em cláusulas catch porque realmente não há como saber qual tipo uma exceção terá. Você pode lançar objetos de qualquer tipo e exceções geradas pelo sistema (como exceção de falta de memória) tecnicamente podem acontecer a qualquer momento. Mesmo que tivéssemos uma noção de anotações de throws semelhante ao Java, não está claro que poderíamos realmente confiá-las. (E, também não está claro que elas funcionem tão bem no Java, mas isso é outra discussão.)_

Não restringimos nenhum tipo em guardas de tipo a menos que saibamos o tipo exato para o qual você está restringindo. Por exemplo, se você verificar typeof x === "string", nós de fato restringiremos um any para string porque sabemos com certeza que esse é o tipo exato de x. Isso não é o caso com instanceof. Especificamente, você pode verificar x instanceof Base, mas x pode realmente ser uma instância de uma classe derivada de Base. Se restringíssemos x ao tipo Base, você veria erros ao acessar propriedades da classe derivada mesmo que não haja nada de errado com o código. Agora, antes de argumentar que esses erros seriam aceitáveis, tenha em mente que o tipo declarado de x é any, então você já disse que não quer nenhuma verificação. Nós consideramos isso como uma indicação de que devemos emitir erros apenas quando temos 100% de certeza de que são erros. E só sabemos disso se conhecermos o tipo exato.

Resposta #1

Pelo que eu sei, você não pode especificar um tipo em uma cláusula catch, porque isso sugeriria que você está capturando apenas um determinado tipo de erro, o que não é possível na linguagem.

A solução comum para obter uma variável tipada é declarar uma variável local imediatamente dentro do bloco catch:

catch(e) {
  const err: firebase.firestore.FirestoreError = e;
}

Veja também esta discussão sobre o tema: https://github.com/microsoft/TypeScript/issues/8677#issuecomment-220385124

Resposta #2

Eu tentei isso, e resolvi meu problema

Eu uso instanceof

try {
  await signInWithCredential(auth, authProvider)
} catch (e) {
  const err = e instanceof FirebaseError
  if(err){
    console.log(e.code)
  }
}

}

Artigos relacionados