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)
}
}
}
