2013-08-15 7 views
10

Sto riscontrando uno strano comportamento con instanceof in NodeJs. Sto provando a creare un modulo che genera eccezioni che possono essere catturate consumando moduli e gestite in base al tipo di eccezione. Tuttavia, la chiamata per verificare il tipo "instanceof di mod.MyException" restituisce sempre false.Nodejs + Richiede istanza di comportamento

mymodule.js:

function MyException() {} 
MyException.prototype = new Error(); 
MyException.prototype.constructor = MyException; 

function Foo() { 
    throw new MyException(); 
} 

exports.Foo = Foo; 
exports.MyException = MyException; 

myconsumingmodule.js

var mod = require('mymodule'); 

try { 
    mod.Foo(); 
} catch (error) { 
    if (error instanceof mod.MyException) { // always returns false 
     //do error specific handling (never executes) 
     return; 
    } 
    // generic handling 
} 

Se faccio il test instanceof in mymodule.js in questo modo si restituisce true

mymodule .js

var a = new MyException() 
console.log(a instanceof MyException); //true 

Tuttavia se creare un'eccezione nel modulo che consumano e provarlo identifica correttamente come MyException, non lo fa solo quando si confrontano contro un'eccezione che è stato creato da l'altro modulo.

myconsumingmodule.js

var mod = require('mymodule') 
var b = new mod.MyException(); 
console.log(b instanceof mod.MyException); // true 
+0

funziona per me sul nodo 0.10.5 – soulcheck

+0

@Eriedor, hai mai trovato una soluzione a questo problema? – jayarjo

+0

Temo di non averlo, ho abbandonato il tentativo di risolvere questo problema e non l'ho rivisitato per vedere se è stato risolto in una versione successiva del nodo. – Eriedor

risposta

0

non possono riprodurre il problema. Lavorando per me utilizzando la versione 0.12 e 4.0.0 (testati entrambi).

Quello che dovresti considerare in futuro è che fai riferimento ai tuoi moduli PROPRI utilizzando i percorsi relativi (quelli assoluti non sono indipendenti dal sistema). In caso contrario, normalmente si fa riferimento ai moduli principali di Node.js direttamente o a quelli installati su NPM. Quindi cambia 'mymodule' in './mymodule' (cambia percorso di conseguenza).

6

TROVATO IT

Per utilizzare il vostro esempio, nel file di one.js ho avuto:

var mod = require('mymodule'); 

ma in un'altra lima two.js ho avuto:

var mod = require('Mymodule'); 

e tutto sembrava funzionare esattamente lo stesso, tranne quando è stato confrontato un errore creato da one.js utilizzando instanceof in two.js!.

Assurdamente, node.js ti permette di fare un case-insensitive richiedono, ad eccezione non è davvero-case insensitive, in realtà richiede il file due volte, che è il motivo per cui i rendimenti instanceoffalse - i costruttori sono due funzioni diverse da due diverse istanze del modulo!

TL; DR

assicurarsi che tutti i require stringhe sono coerenti e minuscole.

+1

Vorrei poter dare questo più di un voto. Dopo ore di ricerche su questo (che si è conclusa con la maggior parte delle persone che rispondono ad altre domande) avevo quasi rinunciato. In un file ho avuto il caso sbagliato. Cambiato e Voilà! Scommetto che sei su un Mac (come me) che ha una semantica di file system che ignora i casi e che ignora i casi. Non penso che sia colpa di NodeJS. Si prega di contrassegnare questo come risposta. –

+1

Un'altra cosa che vale la pena menzionare (perché mi sono imbattuto in essa) è che anche i diversi percorsi del file avranno questo effetto. Quindi 'a/b/c.js' riferimento a' ../../ d.js' e 'a/b.js' riferimento a' ../ d.js' richiederà 'd.js' due volte ... –

+0

Incredibilmente utile: ho risolto il mio stesso problema, difficile da diagnosticare. Grazie. Come James Keesey, sono su un Mac. –