W JS nie wydaje się możliwe sprawdzenie, czy argument przekazany do funkcji jest rzeczywiście typu „błąd”, czy też wystąpieniem błędu.
Na przykład to nie jest prawidłowe:
typeof err === 'error'
ponieważ istnieje tylko 6 możliwych typów (w postaci ciągów):
Operator typeof zwraca informacje o typie w postaci ciągu. Istnieje sześć możliwych wartości, które typeof
zwracają:
„liczba”, „ciąg znaków”, „wartość logiczna”, „obiekt”, „funkcja” i „nieokreślona”.
Ale co, jeśli mam taki prosty przypadek użycia:
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);
}
}
więc jaki jest najlepszy sposób określenia, czy argument jest wystąpieniem błędu?
czy instanceof
operator ma jakąś pomoc?
javascript
node.js
Alexander Mills
źródło
źródło
err instanceof Error
err
(powiedzmy) ramkę iframe, a następnie przekażesz ją do okna nadrzędnego w celu przekazania, otrzymasz(err instanceof Error) === false
. Dzieje się tak, ponieważ element iframe i jego okno nadrzędne mają różne, różneError
prototypy obiektów. Podobnie obiekt taki jakobj = {};
will, przekazany do funkcji działającej w innym oknie, yeild(obj instanceof Object)===false
. (Co gorsza, w IE, jeśli zachowasz odniesienie do obj po zniszczeniu lub nawigacji w jego oknie, próba wywołania prototypu obiektu fns, takiego jak,obj.hasOwnProperty()
spowoduje wyświetlenie błędów!)catch((err)=>{if (err === ENOENT)
zwracaENOENT is not defined
błąd?Odpowiedzi:
Możesz użyć
instanceof
operatora (ale zobacz zastrzeżenie poniżej!).Powyższe nie zadziała, jeśli błąd został zgłoszony w innym oknie / ramce / ramce iframe niż ta, w której odbywa się sprawdzanie. W takim przypadku
instanceof Error
sprawdzenie zwróci fałsz, nawet dlaError
obiektu. W takim przypadku najłatwiejszym podejściem jest pisanie na klawiaturze.Jednak pisanie typu kaczego może generować fałszywe alarmy, jeśli masz obiekty bez błędów, które zawierają
stack
imessage
właściwości.źródło
ReferenceError
instancją. SprawdzaszReferenceError
obiekt globalny . Spróbuj tego:try { foo } catch (e) { console.log(e instanceof Error) }
rejestrujetrue
. JeśliReferenceError
z jakiegoś powodu próbujesz sprawdzić obiekt globalny , możesz użyćError.isPrototypeOf(ReferenceError)
ReferenceError
instancje nie były instancjamiError
. Było to spowodowane wezwaniem dovm.runInNewContext()
w węźle, w którym wszystkie standardowe prototypy są przedefiniowane. Wszystkie moje wyniki nie były instancjami standardowych obiektów. Szukałem w SO o tym i wpadłem w ten wątek :)const error = (err instanceof Error || err instanceof TypeError) ? err : new Error(err.message ? err.message : err);
instanceof
to określony rodzaj błędu?Zadałem oryginalne pytanie - odpowiedź @ Trott jest z pewnością najlepsza.
Jednak ze względu na to, że JS jest językiem dynamicznym i jest tak wiele środowisk wykonawczych JS,
instanceof
operator może zawieść, szczególnie w przypadku programowania front-end, gdy przekracza granice, takie jak ramki iframe. Zobacz: https://github.com/mrdoob/three.js/issues/5886Jeśli nie przeszkadza ci pisanie kaczkami, to powinno być dobre:
Osobiście wolę języki statyczne, ale jeśli używasz języka dynamicznego, najlepiej jest objąć język dynamiczny takim, jakim jest, zamiast zmuszać go do zachowywania się jak język z typowaniem statycznym.
jeśli chcesz uzyskać dokładniejsze informacje, możesz zrobić to:
źródło
instanceof
operator w niektórych przypadkach nie działa, zobacz powiązany artykuł.Error
,ReferenceError
...). A w moim środowiskuinstanceof
w wielu okolicznościach zawodzi.Jedyny problem z tym jest
Alternatywą byłoby użycie właściwości constructor.
Chociaż należy zauważyć, że to dopasowanie jest bardzo specyficzne, na przykład:
źródło
Możesz użyć,
Object.prototype.toString
aby łatwo sprawdzić, czy obiekt jestError
, który będzie działał również dla różnych ramek.źródło
Możesz użyć obj.constructor.name, aby sprawdzić „klasę” obiektu https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
Na przykład
Powyższa linia zarejestruje „Błąd”, który jest nazwą klasy obiektu. Można tego użyć z dowolnymi klasami w javascript, jeśli klasa nie używa właściwości o nazwie „nazwa”
źródło
Dzięki @Trott za twój kod, właśnie użyłem tego samego kodu i dodałem przykład pracy w czasie rzeczywistym dla dobra innych.
źródło
Lub użyj tego do różnych typów błędów
źródło