Estou tentando estender o erro com ES6 e Babel. Não está dando certo.
class MyError extends Error {
constructor(m) {
super(m);
}
}
var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string
O objeto Erro nunca recebe o conjunto de mensagens correto.
Agora, já vi algumas soluções em SO ( por exemplo, aqui ), mas todas parecem muito pouco compatíveis com o ES6-y. Como fazer isso de uma maneira agradável, no ES6? (Isso está trabalhando em Babel)
javascript
ecmascript-6
babeljs
transpiler
Karel Bílek
fonte
fonte
Respostas:
Com base na resposta de Karel Bílek, eu faria uma pequena alteração no
constructor
:Isso será impresso
MyError
na pilha, e não no genéricoError
.Ele também adicionará a mensagem de erro ao rastreamento de pilha - que estava ausente no exemplo de Karel.
Também será usado
captureStackTrace
se estiver disponível.Com o Babel 6, você precisa transformar o built -in- extension ( npm ) para que isso funcione.
fonte
if (typeof Error.captureStackTrace === 'function') { Error.captureStackTrace(this, this.constructor.name) } else { this.stack = (new Error(message)).stack; }
. Eu diria que é melhor usar essa função se estiver disponível, pois ela fornece uma pilha de chamadas mais 'nativa' e imprime o nome do objeto de erro. Obviamente, se você estiver usando isso somente no lado do servidor (Nó), também não será um problema.this.stack = (new Error(message)).stack
você recebe isso ... mas, na prática, isso provavelmente não é um grande problema.new MyError('foo') instanceof MyError === false
extendable-error-class
npmjs.com/package/extendable-error-class que é conveniente para evitar uma dependência em Babel-plug-in-transformar-embutida-estenderthis.message = message;
é redundante comsuper(message);
Combinando esta resposta , esta resposta e este código , criei esta pequena classe "auxiliar", que parece funcionar bem.
Experimente no REPL
fonte
this.stack = (new Error(message)).stack;
- caso contrário, a mensagem está faltando no stacktracemessage
construtor Error na pilha, para mostrar a mensagem correta no topo da pilha quando lançada:this.stack = (new Error(message)).stack;
myerror.name
agora retorna "Erro". Não sei se isso está relacionado com versões posteriores do babel.See @ Sukima de resposta abaixoPara finalmente colocar isso para descansar. Em Babel 6 é explícito que os desenvolvedores não suportam que se estende desde construído em. Embora este truque não vai ajudar com coisas como
Map
,Set
, etc. ela não funciona paraError
. Isso é importante, pois uma das idéias principais de uma linguagem que pode gerar uma exceção é permitir erros personalizados. Isso é duplamente importante, pois as promessas se tornam mais úteis, pois são projetadas para rejeitar um erro .A triste verdade é que você ainda precisa fazer isso da maneira antiga no ES2015.
Exemplo no Babel REPL
Padrão de erro personalizado
Por outro lado, existe um plugin para o Babel 6 para permitir isso.
https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Atualização: (a partir de 29/09/2016) Após alguns testes, parece que o babel.io não responde adequadamente por todas as declarações (estendendo-se de um erro estendido personalizado). Mas no Ember.JS, a extensão de Erro funciona conforme o esperado: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce
fonte
Error.toString()
. A necessidade de fazer aros e giros especiais para conseguir isso significa que a maioria dos desenvolvedores o evitará e recorrerá a práticas ruins, como jogar cordas em vez de Erros. Ou criando seu próprio mapa como objetos. Por que a necessidade de impedir esses métodos de POO?Edit : Quebrando alterações no TypeScript 2.1
Editar a resposta original de Lee Benson funciona um pouco para mim. Isso também adiciona
stack
métodos adicionais deExtendableError
classe à instância.fonte
Object.setPrototypeOf
oMyError
construtor também. stackoverflow.com/a/41102306/186334 github.com/Microsoft/TypeScript-wiki/blob/master/…Com as alterações mais recentes no babel 6, acho que o transform-builtin-extend não está mais funcionando. Acabei usando essa abordagem mista:
e
Como resultado, todos esses testes passam:
fonte
Citação
Embora os códigos acima não podem produzir o rastreio da pilha, a menos que
this.stack = (new Error()).stack;
ouError.captureStackTrace(this, this.constructor.name);
é invocado em Babel . OMI, talvez um problema aqui.Na verdade, o rastreamento de pilha pode ser gerado sob
Chrome console
eNode.js v4.2.1
com esses trechos de código.Saída de
Chrome console
.Saída de
Node.js
fonte
Além da resposta @zangw, você pode definir seus erros assim:
que lança nome, mensagem e rastreamento de pilha corretos:
fonte
new MyError('foo') instanceof MyError === false
.Node.js v7.7.3
.Essa
class MyError extends Error {…}
sintaxe está correta.Observe que os transpilers ainda têm problemas com a herança de objetos internos. No seu caso,
parece corrigir o problema.
fonte
Error.call()
retorna uma nova instância de erro para mim.Dado isso, a resposta aceita não funciona mais, você sempre pode usar uma fábrica como alternativa ( repl ):
fonte
Eu prefiro uma sintaxe mais forte do que a descrita acima. Métodos adicionais no tipo de erro ajudarão você a criar bonito
console.log
ou algo mais.Para testar esse código, você pode executar algo semelhante:
A extensão do
CustomError
tipo é bem-vinda. É possível adicionar alguma funcionalidade específica ao tipo estendido ou substituir existente. Por exemplo.fonte
Como o @sukima menciona, você não pode estender o JS nativo. A pergunta do OP não pode ser respondida.
Semelhante à resposta de Melbourne2991 , usei uma fábrica, mas segui a recomendação da MDN para os tipos de erro do cliente .
fonte
Isso funciona para mim:
fonte
Não usando Babel, mas no ES6 simples, o seguinte parece funcionar bem para mim:
Teste do REPL:
Como você pode ver, a pilha contém o nome do erro e a mensagem. Não tenho certeza se estou perdendo alguma coisa, mas todas as outras respostas parecem complicar demais as coisas.
fonte
Melhorei um pouco a solução do @Lee Benson desta maneira:
extendableError.js
um exemplo de erro
Em seguida, você pode agrupar erros enquanto possui especificadores de opção para decidir o que fazer de maneira diferente em algumas situações específicas do aplicativo
fonte