Vreau să arunce unele lucruri în codul de JS și vreau ca ei să fie instanceof Eroare, dar, de asemenea, vreau să le fi altceva.
În Python, de obicei, unul ar subclasa Excepție.
Ce's corespunzătoare de lucru pentru a face în JS?
Singurul standard de Eroare câmp obiect a este "mesaj" de proprietate. (A se vedea MDN, sau EcmaScript Limba caietul de sarcini, secțiunea 15.11) Totul altceva este platforma specifice.
Mosts medii stabilite "stivă" de proprietate, dar, fileName
și lineNumber
sunt practic inutile pentru a fi utilizate în moștenire.
Deci, abordare minimalistă este:
function MyError(message) {
this.name = 'MyError';
this.message = message;
this.stack = (new Error()).stack;
}
MyError.prototype = new Error; // <-- remove this if you do not
// want MyError to be instanceof Error
Ai putea mirosi stiva, unshift elemente nedorite din ea și de a extrage informații cum ar fi numele fișierului și lineNumber, dar acest lucru necesită informații despre platforma JavaScript rulează în prezent pe. Cele mai multe cazuri că este inutilă ... și poți să o faci în post-mortem, dacă vrei cu adevărat.
Safari este o excepție notabilă. Nu există nici o "stivă" de proprietate, dar "arunca" cuvinte cheie seturi de sourceURL " și " linia de proprietăți a obiectului care este aruncat. Aceste lucruri sunt garantate a fi corecte.
Cazuri de testare am folosit pot fi găsite aici: JavaScript auto-a făcut Eroare obiect comparație.
Edit: vă Rugăm să citiți comentarii. Se pare că aceasta funcționează numai bine în V8 (Chrome / Node.JS) intenția Mea a fost de a oferi o soluție cross-browser, care să lucreze în toate browserele, și să ofere stivei în cazul în care sprijinul este acolo.
Edit: am făcut această Comunitate Wiki pentru a permite mai mult de editare.
Soluție pentru V8 (Chrome / Node.JS), funcționează în Firefox, și pot fi modificate în funcție de cea mai mare parte corect in IE. (a se vedea sfârșitul de post)
function UserError(message) {
this.constructor.prototype.__proto__ = Error.prototype // Make this an instanceof Error.
Error.call(this) // Does not seem necessary. Perhaps remove this line?
Error.captureStackTrace(this, this.constructor) // Creates the this.stack getter
this.name = this.constructor.name; // Used to cause messages like "UserError: message" instead of the default "Error: message"
this.message = message; // Used to set the message
}
Original post pe "Arată-mi codul !"
Versiunea scurta:
function UserError(message) {
this.constructor.prototype.__proto__ = Error.prototype
Error.captureStackTrace(this, this.constructor)
this.name = this.constructor.name
this.message = message
}
Eu tot asta.constructor.prototip.proto = Eroare.prototip` in interiorul functiei pentru a păstra toate codul împreună. Dar puteți înlocui, de asemenea, acest lucru.constructor " cu " UserError și care vă permite să mutați codul în afara funcției, a sunat o dată.
Dacă te duci această rută, asigurați-vă că sunați linia înainte prima dată când arunca UserError
.
Acest avertisment nu se aplică funcția, pentru că funcțiile sunt create în primul rând, nu conteaza ordinea. Astfel, aveți posibilitatea să mutați funcția la sfârșitul fișierului, fără nici o problemă.
Compatibilitate Browser-Ul
Funcționează în Firefox și Chrome (și Node.JS) și umple toate promisiunile.
Internet Explorer eșuează în următoarele
Erorile nu au `err.stiva pentru a începe cu, deci, "l', nu e vina mea".
Eroare.captureStackTrace(asta, asta.constructor)
nu exista deci trebuie să faci ceva ca
dacă(Eroare.captureStackTrace) // AKA daca nu IE Eroare.captureStackTrace(asta, asta.constructor)
toString
încetează să mai existe atunci când subclasa "Eroare". Așa că, de asemenea, nevoie pentru a adăuga.altceva acest lucru.toString = function () { întoarcere asta.numele + ': ' + acest lucru.mesaj }
UserError
sa fie un instanceof Eroare
dacă tu a alerga după ceva timp înainte de a vă arunca UserError`UserError.prototip = Eroare.prototip
Pe scurt:
clasa CustomError se extinde de Eroare { / ... /}
Opțiunea 1: folosiți babel-plugin-transform-builtin-extend
Opțiunea 2: do it yourself (inspirat din aceeași bibliotecă)
function CustomError(...args) {
const instance = Reflect.construct(Error, args);
Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));
return instance;
}
CustomError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
Reflect.setPrototypeOf(CustomError, Error);
funcția CustomError(mesaj, nume de fișier, lineNumber) { var exemplu = new Eroare(mesaj, nume de fișier, lineNumber); Obiect.setPrototypeOf(de exemplu, Obiect.getPrototypeOf(asta)); reveni exemplu; } CustomError.prototip = Obiect.crea(Eroare.prototype, { constructor: { valoare: Eroare, enumerable: fals, scriere: adevărat, configurabil: adevărat } }); dacă (Obiect.setPrototypeOf){ Obiect.setPrototypeOf(CustomError, Eroare); } else { CustomError.proto = Eroare; }
Explicație:
De ce extinderea Eroare de clasa folosind ES6 și Babel este o problemă?
Pentru un exemplu de CustomError nu mai este recunoscut ca atare.
class CustomError extends Error {}
console.log(new CustomError('test') instanceof Error);// true
console.log(new CustomError('test') instanceof CustomError);// false
În fapt, din documentația oficială de Babel, tu nu se poate extinde la orice built-in JavaScript clase cum ar fi "Data", "Matrice", DOM
sau "Eroare".
Problema este descris aici:
Ce despre alte ASTFEL de răspunsuri?
Toate răspunsurile date repara instanceof
problema, dar pierzi regulat de eroare consola.log
:
console.log(new CustomError('test'));
// output:
// CustomError {name: "MyError", message: "test", stack: "Error↵ at CustomError (<anonymous>:4:19)↵ at <anonymous>:1:5"}
Întrucât utilizarea metodei menționate mai sus, nu numai tu fix instanceof
problema dar, de asemenea, să păstreze regulat de eroare consola.log
:
console.log(new CustomError('test'));
// output:
// Error: test
// at CustomError (<anonymous>:2:32)
// at <anonymous>:1:5
A pentru a evita șabloane pentru fiecare tip diferit de eroare, am combinat înțelepciunea unora dintre soluțiile într-un `createErrorType funcția:
function createErrorType(name, init) {
function E(message) {
if (!Error.captureStackTrace)
this.stack = (new Error()).stack;
else
Error.captureStackTrace(this, this.constructor);
this.message = message;
init && init.apply(this, arguments);
}
E.prototype = new Error();
E.prototype.name = name;
E.prototype.constructor = E;
return E;
}
Apoi, puteți definirea de noi tipuri de eroare cu ușurință, după cum urmează:
var NameError = createErrorType('NameError', function (name, invalidChar) {
this.message = 'The name ' + name + ' may not contain ' + invalidChar;
});
var UnboundError = createErrorType('UnboundError', function (variableName) {
this.message = 'Variable ' + variableName + ' is not bound';
});
În 2018cred că acest lucru este cel mai bun mod; care acceptă IE9+ și browserele moderne.
UPDATE: a se Vedea acest test și repo pentru comparație pe diferite implementari.
function CustomError(message) {
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: 'CustomError'
});
Object.defineProperty(this, 'message', {
enumerable: false,
writable: true,
value: message
});
if (Error.hasOwnProperty('captureStackTrace')) { // V8
Error.captureStackTrace(this, CustomError);
} else {
Object.defineProperty(this, 'stack', {
enumerable: false,
writable: false,
value: (new Error(message)).stack
});
}
}
if (typeof Object.setPrototypeOf === 'function') {
Object.setPrototypeOf(CustomError.prototype, Error.prototype);
} else {
CustomError.prototype = Object.create(Error.prototype, {
constructor: { value: CustomError }
});
}
De asemenea, feriți-vă că `proto proprietatea este învechit, care este utilizat pe scară largă în alte răspunsuri.
Pentru motive de exhaustivitate-doar pentru că niciunul dintre răspunsurile anterioare menționat această metodă-dacă sunteți de lucru cu Node.js și don't trebuie să aibă grijă de compatibilitate browser-ul, efectul dorit este destul de ușor de realizat cu construit în moștenește
a util
module (documente oficiale aici).
De exemplu, să's presupunem că doriți să creați o eroare personalizate clasa care are un cod de eroare ca primul argument și un mesaj de eroare ca cel de-al doilea argument:
fișier custom-error.js:
'use strict';
var util = require('util');
function CustomError(code, message) {
Error.captureStackTrace(this, CustomError);
this.name = CustomError.name;
this.code = code;
this.message = message;
}
util.inherits(CustomError, Error);
module.exports = CustomError;
Acum poti instantia și trece/arunca CustomError
:
var CustomError = require('./path/to/custom-error');
// pass as the first argument to your callback
callback(new CustomError(404, 'Not found!'));
// or, if you are working with try/catch, throw it
throw new CustomError(500, 'Server Error!');
Rețineți că, cu acest fragment, stack trace-ul va avea corecta nume de fișier și de linie, și eroarea exemplu va avea numele corect!
Acest lucru se întâmplă din cauza utilizării de captureStackTracemetoda, care creează o "stivă" de proprietate asupra obiectului țintă (în acest caz,
CustomError` a fi instanțiată). Pentru mai multe detalii despre cum funcționează, verificați documentația aici.
Crescent Proaspete's a răspunde foarte-au votat răspunsul este înșelătoare. Deși avertismentele sale nu sunt valide, există și alte limitări care el nu't adresa.
În primul rând, raționamentul în Crescent's "Avertismente:" alineatul se't sens. Explicația implică faptul că codificare "o grămadă de if (eroare instanceof MyError) altceva ..." este oarecum împovărătoare sau verbose în comparație cu mai multe declarațiilor de captură. Mai multe instanceof declarații într-un singur bloc catch sunt doar la fel de concis ca prinde mai multe declarații, curat și concis cod fără trucuri. Aceasta este o modalitate foarte bună de a emula Java's mare throwable--subtip specific de tratare a erorilor.
WRT "apare mesajul de proprietate din subclasa nu ia set", că nu este cazul dacă utilizați un construite în mod corespunzător de Eroare subclasă. Pentru a face propriile ErrorX Eroare subclasa, doar copiați bloc începe cu "var MyError =", schimbând un singur cuvânt "MyError" pentru "ErrorX". (Dacă doriți să adăugați personalizate, metode de subclasă, urmați eșantion de text).
Real și limitare semnificativă de eroare JavaScript subclasarea este că pentru JavaScript implementări sau debugger-ele care urmări și raporta asupra stivei și locația de instanțiere, cum ar fi FireFox, o locație în propria Eroare subclasă de implementare vor fi înregistrate ca instanțierea punct de clasă, întrucât, dacă ai folosit-o direct de Eroare, ar fi locul unde ai fugit "noua Eroare(...)"). De EXEMPLU, utilizatorii ar fi, probabil, niciodată nu a observat, dar utilizatorii de Foc Bug pe FF va vedea inutil nume de fișier și numărul de linie valorile raportate alături de aceste Erori, și va trebui pentru a detalia în jos, pe stack trace element #1 pentru a găsi adevăratul instanțierea locație.
Cât despre această soluție?
În loc de a arunca-ți de Eroare personalizate folosind:
throw new MyError("Oops!");
Ai folie de Eroare de obiect (ca un fel de Decorator):
throw new MyError(Error("Oops!"));
Acest lucru face sigur că toate atributele sunt corecte, cum ar fi stiva, fileName lineNumber, et cetera.
Tot ce trebuie să faci apoi este fie copiați atributele, sau defini getters pentru ei. Aici este un exemplu folosind getters (IE9):
function MyError(wrapped)
{
this.wrapped = wrapped;
this.wrapped.name = 'MyError';
}
function wrap(attr)
{
Object.defineProperty(MyError.prototype, attr, {
get: function()
{
return this.wrapped[attr];
}
});
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;
wrap('name');
wrap('message');
wrap('stack');
wrap('fileName');
wrap('lineNumber');
wrap('columnNumber');
MyError.prototype.toString = function()
{
return this.wrapped.toString();
};
Soluția mea este mult mai simplu decât alte răspunsuri furnizate și nu't au dezavantaje.
Se pastreaza Eroare lanț prototip și toate proprietățile pe Eroare fără a avea nevoie de cunoștințe specifice dintre ele. L's a fost testat în Chrome, Firefox, Nod, și IE11.
Singura limitare este o intrare în plus la partea de sus a stiva de apeluri. Dar care este ușor de ignorat.
Aici's un exemplu cu doi parametrii personalizate:
function CustomError(message, param1, param2) {
var err = new Error(message);
Object.setPrototypeOf(err, CustomError.prototype);
err.param1 = param1;
err.param2 = param2;
return err;
}
CustomError.prototype = Object.create(
Error.prototype,
{name: {value: 'CustomError', enumerable: false}}
);
Exemplu De Utilizare:
try {
throw new CustomError('Something Unexpected Happened!', 1234, 'neat');
} catch (ex) {
console.log(ex.name); //CustomError
console.log(ex.message); //Something Unexpected Happened!
console.log(ex.param1); //1234
console.log(ex.param2); //neat
console.log(ex.stack); //stacktrace
console.log(ex instanceof Error); //true
console.log(ex instanceof CustomError); //true
}
Pentru medii care necesită o polyfil de setPrototypeOf:
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
obj.__proto__ = proto;
return obj;
};
În exemplul de mai sus Eroare.aplica
(, de asemenea, Eroare.sun
) nu't face nimic pentru mine (Firefox 3.6/Chrome 5). O soluție pe care o folosesc este:
function MyError(message, fileName, lineNumber) {
var err = new Error();
if (err.stack) {
// remove one stack level:
if (typeof(Components) != 'undefined') {
// Mozilla:
this.stack = err.stack.substring(err.stack.indexOf('\n')+1);
}
else if (typeof(chrome) != 'undefined' || typeof(process) != 'undefined') {
// Google Chrome/Node.js:
this.stack = err.stack.replace(/\n[^\n]*/,'');
}
else {
this.stack = err.stack;
}
}
this.message = message === undefined ? err.message : message;
this.fileName = fileName === undefined ? err.fileName : fileName;
this.lineNumber = lineNumber === undefined ? err.lineNumber : lineNumber;
}
MyError.prototype = new Error();
MyError.prototype.constructor = MyError;
MyError.prototype.name = 'MyError';
Așa cum au spus unii, l's destul de ușor cu ES6:
class CustomError extends Error { }
Așa că am încercat asta în aplicația mea, (Unghiulare, mașina de Scris) și l-am't de lucru. După un timp m-am'am constatat că problema vine de la mașina de Scris :O
Vezi https://github.com/Microsoft/TypeScript/issues/13965
L's foarte deranjant pentru că dacă o faci:
class CustomError extends Error {}
try {
throw new CustomError()
} catch(e) {
if (e instanceof CustomError) {
console.log('Custom error');
} else {
console.log('Basic error');
}
}
În nod sau direct în browser-l'll display: eroare Personalizate
Încercați să executați cu mașina de Scris în proiectul dumneavoastră pe mașina de Scris de joacă pentru copii, it'll de afișare de Bază de eroare`...
Soluția este de a face următoarele:
class CustomError extends Error {
// we have to do the following because of: https://github.com/Microsoft/TypeScript/issues/13965
// otherwise we cannot use instanceof later to catch a given type
public __proto__: Error;
constructor(message?: string) {
const trueProto = new.target.prototype;
super(message);
this.__proto__ = trueProto;
}
}
Vreau doar să adaug la ceea ce alții au declarat deja:
Să asigurați-vă că obiceiul de eroare de clasă apare corect în stack trace-ul, aveți nevoie pentru a stabili eroare personalizate clasa's prototip's nume de proprietate de eroare personalizate clasa's nume de proprietate. Aceasta este ceea ce vreau să spun:
CustomError.prototype = Error.prototype;
CustomError.prototype.name = 'CustomError';
Atât de completă exemplu ar fi:
var CustomError = function(message) {
var err = new Error(message);
err.name = 'CustomError';
this.name = err.name;
this.message = err.message;
//check if there is a stack property supported in browser
if (err.stack) {
this.stack = err.stack;
}
//we should define how our toString function works as this will be used internally
//by the browser's stack trace generation function
this.toString = function() {
return this.name + ': ' + this.message;
};
};
CustomError.prototype = new Error();
CustomError.prototype.name = 'CustomError';
Când totul este spus și făcut, aruncă nouă excepție și se pare ca acest lucru (am alene încercat acest lucru în chrome dev tools):
CustomError: Stuff Happened. GASP!
at Error.CustomError (<anonymous>:3:19)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:603:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:562:52)
at Object.InjectedScript.evaluate (<anonymous>:481:21)
My 2 cents:
a) Pentru accesarea `Eroare.stiva de proprietate (ca în unele răspunsuri) au o mare penalizare de performanță.
b) Pentru că e o singură linie.
c) Pentru că soluția la https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error nu pare a păstra stiva de informații.
//MyError class constructor
function MyError(msg){
this.__proto__.__proto__ = Error.apply(null, arguments);
};
exemplu de utilizare
acest lucru.__proto__.__proto__ "este" MyError.prototip.__proto__
, deci este setarea __proto__
PENTRU TOATE CAZURILE
de MyError la o anumită nou creat de Eroare. Se păstrează MyError clasa de proprietăți și metode și, de asemenea, pune noua Eroare de proprietăți (inclusiv .stiva) înproto lanțului.
Nu poti avea mai mult de o instanță de MyError utile cu stiva de informații.
Nu folosiți această soluție dacă nu înțeleg pe deplin ceea ce asta.__proto__.__proto__=
nu.
În Nodul cum au spus și alții, l's simplu:
class DumbError extends Error {
constructor(foo = 'bar', ...params) {
super(...params);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, DumbError);
}
this.name = 'DumbError';
this.foo = foo;
this.date = new Date();
}
}
try {
let x = 3;
if (x < 10) {
throw new DumbError();
}
} catch (error) {
console.log(error);
}
Deoarece JavaScript Excepții sunt dificil de sub-clasa, nu't sub-clasa. Am crea o nouă Excepție de clasă și de a folosi o Eroare în interiorul de ea. Schimb de Eroare.numele de proprietate, astfel încât se pare ca obiceiul meu de excepție pe consola:
var InvalidInputError = function(message) {
var error = new Error(message);
error.name = 'InvalidInputError';
return error;
};
Mai nou excepție pot fi aruncate doar ca o Eroare și va funcționa cum era de așteptat, de exemplu:
throw new InvalidInputError("Input must be a string");
// Output: Uncaught InvalidInputError: Input must be a string
Avertisment: stack trace-ul nu este perfect, ca se va aduce la în cazul în care noul Eroare este creat și nu în cazul în care arunca. Aceasta nu este o afacere mare pe Chrome, deoarece vă oferă un full stack trace-ul direct in consola. Dar's mai problematice pe Firefox, de exemplu.
După cum a subliniat în Mohsen's a răspunde, în ES6-l's posibil să se extindă erori folosind clase. L's mult mai ușor și comportamentul lor este mai consistent cu nativ erori...dar din pacate l's nu este o chestiune simplă de a folosi acest lucru în browser-ul, dacă aveți nevoie de suport pre-ES6 browsere. Vezi mai jos pentru unele note privind modul în care ar putea fi puse în aplicare, dar în același timp îți sugerez un relativ simplă abordare care include unele dintre cele mai bune sugestii de la alte răspunsuri:
function CustomError(message) {
//This is for future compatibility with the ES6 version, which
//would display a similar message if invoked without the
//`new` operator.
if (!(this instanceof CustomError)) {
throw new TypeError("Constructor 'CustomError' cannot be invoked without 'new'");
}
this.message = message;
//Stack trace in V8
if (Error.captureStackTrace) {
Error.captureStackTrace(this, CustomError);
}
else this.stack = (new Error).stack;
}
CustomError.prototype = Object.create(Error.prototype);
CustomError.prototype.name = 'CustomError';
În ES6-l's la fel de simplu ca:
class CustomError extends Error {}
...și vă poate detecta suport pentru ES6 clase cu try {eval('class X{}'), dar'll obține o eroare de sintaxă dacă încercați să includă ES6 versiune într-un script care's încărcat de browsere mai vechi. Deci, singura modalitate de a sprijini toate browserele ar fi să încărcați un script separat în mod dinamic (de exemplu, prin intermediul AJAX sau
eval()) pentru browserele care acceptă ES6. O altă complicație este că
eval()` e't sprijinit în toate mediile (datorită Conținutului Politicilor de Securitate), care poate sau nu poate fi un considerent pentru proiectul dumneavoastră.
Deci, de acum, fie prima abordare de mai sus sau pur și simplu folosind "Eroare" direct, fără a încerca să-l extindă pare a fi cel mai bun care poate practic fi făcut pentru codul de care are nevoie pentru a sprijini non-ES6 browsere.
Nu există o altă abordare care unii oameni ar putea dori să ia în considerare, care este de a folosi Obiectul.setPrototypeOf()` unde disponibil pentru a crea o eroare obiect care's un exemplu de eroare personalizate tip, dar care arată și se comportă mai mult ca un nativ de eroare în consolă (datorită Ben's a răspunde pentru recomandare). Aici's mi iau pe asta de abordare: https://gist.github.com/mbrowne/fe45db61cea7858d11be933a998926a8. Dar având în vedere că într-o zi ne-am'll fi capabil de a utiliza doar ES6, personal, am'm nu sunt sigur complexitatea acestei abordări este în valoare de ea.
Modul de a face acest drept este să se întoarcă rezultatul se aplice de la constructor, precum și stabilirea prototip în obicei complicat javascripty mod:
function MyError() {
var tmp = Error.apply(this, arguments);
tmp.name = this.name = 'MyError'
this.stack = tmp.stack
this.message = tmp.message
return this
}
var IntermediateInheritor = function() {}
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor()
var myError = new MyError("message");
console.log("The message is: '"+myError.message+"'") // The message is: 'message'
console.log(myError instanceof Error) // true
console.log(myError instanceof MyError) // true
console.log(myError.toString()) // MyError: message
console.log(myError.stack) // MyError: message \n
// <stack trace ...>
Singurele probleme cu acest mod de a face asta în acest moment (m-am'am reiterat-o un pic) care sunt
Prima problema ar putea fi rezolvată prin iterarea prin toate non-nenumărate proprietăți de eroare folosind truc în acest răspuns: https://stackoverflow.com/questions/8024149/is-it-possible-to-get-the-non-enumerable-inherited-property-names-of-an-object, dar acest lucru nu't este suportat de ie<9. A doua problemă ar putea fi rezolvată prin ruperea in stack trace-ul, dar am'm nu sunt sigur cum să în condiții de siguranță face asta (poate doar eliminarea a doua linie de e.stivă.toString() ??).
Aceasta se bazează pe George Bailey's a răspunde, dar se extinde și simplifică idee originală. Este scris în CoffeeScript, dar este ușor să se convertească la JavaScript. Ideea este de a extinde Bailey's de eroare personalizate cu un decorator pe care o înfășoară, permițându-vă să creați personalizat de erori cu ușurință.
Notă: Aceasta va funcționa doar în V8. Nu există nici un suport pentru Eroare.captureStackTrace în alte medii.
Decoratorul nevoie de un nume pentru tipul de eroare, și returnează o funcție care are un mesaj de eroare, și cuprinde de eroare numele.
CoreError = (@message) ->
@constructor.prototype.__proto__ = Error.prototype
Error.captureStackTrace @, @constructor
@name = @constructor.name
BaseError = (type) ->
(message) -> new CoreError "#{ type }Error: #{ message }"
Acum este simplu de a crea noi tipuri de erori.
StorageError = BaseError "Storage"
SignatureError = BaseError "Signature"
Pentru a te distra, ai putea acum să definească o funcție care aruncă o `SignatureError dacă este numit cu prea multe argumente.
f = -> throw SignatureError "too many args" if arguments.length
Acest lucru a fost testat destul de bine și pare să funcționeze perfect pe V8, mențineți traceback, poziție etc.
Notă: Folosind " noi " este opțională atunci când se construiește o eroare personalizate.
Mi-ar lua un pas înapoi și să ia în considerare de ce vrei să faci asta? Cred că ideea este să se ocupe cu diferite erori în mod diferit.
De exemplu, în Python, puteți restricționa declarația de captură pentru a prinde doar MyValidationError
, și, probabil, vrei să fii capabil de a face ceva similar în javascript.
catch (MyValidationError e) {
....
}
Puteți't face acest lucru în javascript. Nu's doar de gând să fie un bloc catch. Te're ar trebui să utilizeze o declarație în cazul în eroare pentru a determina tipul său.
catch(e) { dacă(isMyValidationError(e)) { ... } else { // poate rethrow? arunca-e; } }
Cred că mi-ar, în loc să arunce o prime obiect cu un tip, mesaj, și orice alte proprietăți tu de cuviință.
throw { type: "validation", message: "Invalid timestamp" }
Și când te prind de eroare:
catch(e) {
if(e.type === "validation") {
// handle error
}
// re-throw, or whatever else
}