Em JS, não parece possível verificar se um argumento transmitido para uma função é realmente do tipo 'error' ou uma instância de Error.
Por exemplo, isso não é válido:
typeof err === 'error'
pois existem apenas 6 tipos possíveis (na forma de cadeias):
O operador typeof retorna informações de tipo como uma sequência. Existem seis valores possíveis que typeof
retornam:
"number", "string", "boolean", "object", "function" e "undefined".
Mas e se eu tiver um caso de uso simples como este:
function errorHandler(err) {
if (typeof err === 'error') {
throw err;
}
else {
console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
}
}
então, qual é a melhor maneira de determinar se um argumento é uma instância de Error?
é o instanceof
operador de alguma ajuda?
javascript
node.js
Alexander Mills
fonte
fonte
err instanceof Error
err
(digamos) um iframe, mas depois o passa para a janela principal para entrega, você receberá(err instanceof Error) === false
. Isso ocorre porque o iframe e sua janela pai têmError
protótipos de objetos distintos e diferentes . Da mesma forma, um objeto comoobj = {};
vontade, quando passado para uma função executando em uma janela diferente, também será(obj instanceof Object)===false
. (Mesmo pior, no IE, se você manter uma referência para obj após a sua janela é destruída ou navegado, tentando chamar FNS objeto de protótipo comoobj.hasOwnProperty()
irá lançar erros!)catch((err)=>{if (err === ENOENT)
retornaENOENT is not defined
erro?Respostas:
Você pode usar o
instanceof
operador (mas veja a advertência abaixo!).O procedimento acima não funcionará se o erro foi gerado em uma janela / quadro / iframe diferente daquele em que a verificação está ocorrendo. Nesse caso, a
instanceof Error
verificação retornará false, mesmo para umError
objeto. Nesse caso, a abordagem mais fácil é a digitação de patos.No entanto, pato digitação pode produzir falsos positivos, se você tem objetos não-erro que contêm
stack
emessage
propriedades.fonte
ReferenceError
instância. Você está verificando oReferenceError
objeto global . Tente o seguinte:try { foo } catch (e) { console.log(e instanceof Error) }
Registratrue
. Se você está tentando verificar oReferenceError
objeto global por algum motivo, pode usá-loError.isPrototypeOf(ReferenceError)
ReferenceError
nem todas as minhas instâncias eramError
. Isso ocorreu devido a uma chamadavm.runInNewContext()
no nó, onde todos os protótipos padrão são redefinidos. Todos os meus resultados não foram instâncias de objetos padrão. Eu estava olhando em SO sobre isso, e caiu em esta discussão :)const error = (err instanceof Error || err instanceof TypeError) ? err : new Error(err.message ? err.message : err);
instanceof
tipo específico de erro?Eu fiz a pergunta original - a resposta de @ Trott é certamente a melhor.
No entanto, com o JS sendo uma linguagem dinâmica e com muitos ambientes de tempo de execução JS, o
instanceof
operador pode falhar, especialmente no desenvolvimento de front-end ao cruzar limites, como iframes. Consulte: https://github.com/mrdoob/three.js/issues/5886Se você concorda com a digitação do pato, isso deve ser bom:
Pessoalmente, prefiro idiomas de tipo estaticamente, mas se você estiver usando um idioma dinâmico, é melhor adotar um idioma dinâmico para o que é, em vez de forçá-lo a se comportar como um idioma de tipo estaticamente.
se você quiser ser um pouco mais preciso, faça o seguinte:
fonte
instanceof
falha do operador em alguns casos, consulte o artigo vinculado.Error
,ReferenceError
...). E, no meu ambiente, ainstanceof
falha falha miseravelmente em muitas circunstâncias.O único problema com isso é
Uma alternativa para isso seria usar a propriedade construtor.
Embora seja necessário observar que essa correspondência é muito específica, por exemplo:
fonte
Você pode usar
Object.prototype.toString
para verificar facilmente se um objeto é umError
, o que também funcionará para quadros diferentes.fonte
Você pode usar obj.constructor.name para verificar a "classe" de um objeto https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
Por exemplo
A linha acima registrará "Erro", que é o nome da classe do objeto. Isso pode ser usado com qualquer classe em javascript, se a classe não estiver usando uma propriedade com o nome "name"
fonte
Obrigado @Trott pelo seu código, usei o mesmo código e adicionei um exemplo de trabalho em tempo real para o benefício de outras pessoas.
fonte
Ou use-o para diferentes tipos de erros
fonte