2014-03-29 8 views
10

Ich habe eine Funktion wie folgt aus:JavaScript: Stack-Trace reduzieren, wenn Fehler zu werfen (Punkt-Website zu nennen)

function foo() { 
    throw new Error('`foo` has been removed in favor of `bar`') 
} 

Wenn jemand anruft foo, ich möchte den Stack-Trace (Fehlerausgang) an Punkt die Call-Seite von foo, nicht die throw Linie innerhalb von foo.

Zum Beispiel ich diese:

$ node test.js 

/home/ubuntu/tmp/test.js:2 
    throw new Error('`foo` has been removed in favor of `bar`') 
     ^
Error: `foo` has been removed in favor of `bar` 
    at foo (/home/ubuntu/tmp/test.js:2:9) 
    at Object.<anonymous> (/home/ubuntu/tmp/test.js:5:1) 
    ... 

Wie bekomme ich diese statt?

$ node test.js 

/home/ubuntu/tmp/test.js:5 
    foo() 
^
Error: `foo` has been removed in favor of `bar` 
    at Object.<anonymous> (/home/ubuntu/tmp/test.js:5:1) 
    ... 
+0

Wenn Ihr Ziel Funktionsnamen Anonymität ist, ist dies wahrscheinlich der falsche Ansatz. –

+1

Aber das war, wo Sie den Fehler geworfen haben ... –

+0

Hinweis nur Knoten tut dies. –

Antwort

6

Schritt 1: Definieren Sie ein Objekt benutzerdefinierte Fehler. Für weitere Informationen: A String is not an Error.

function CustomError (msg) { 
    Error.call(this); 

    // By default, V8 limits the stack trace size to 10 frames. 
    Error.stackTraceLimit = 10; 

    // Customizing stack traces 
    Error.prepareStackTrace = function (err, stack) { 
    return stack; 
    }; 

    Error.captureStackTrace(this, arguments.callee); 

    this.message = msg; 
    this.name = 'CustomError'; 
}; 

CustomError.prototype.__proto__ = Error.prototype; 

Schritt 2: Verwenden Domain die nicht erfasste Fehler zu fangen.

function foo() { 
    throw new CustomError('`foo` has been removed in favorof `bar`'); 
}; 

var d = require('domain').create(); 

d.on('error', function(err) { 
    /* 
    * customize the output here. 
    */ 
}); 

d.run(function() { 
    foo(); 
}); 

Schritt 3: die Ausgabe anpassen. Der strukturierte Stack-Trace ist ein Array von CallSite-Objekten, von denen jedes einen Stack-Frame darstellt. Ein CallSite-Objekt definiert these methods.

for(var index=0; index<err.stack.length; index++){ 
    var frame = err.stack[index]; 

    var unit = frame.getFunctionName() || frame.getMethodName(); 
    if (unit === null) { 
     unit = 'function()'; 
    } else { 
     unit += '()' 
    } 

    if (index === 0) { 
     console.error('%s:%d:%d\n %s\n ^', 
     frame.getFileName(), 
     frame.getLineNumber(), 
     frame.getColumnNumber(), 
     unit); 

     console.error('Error: ' + err.message); 

    } else { 
     console.error(' at %s (%s:%d:%d)', 
     unit, 
     frame.getFileName(), 
     frame.getLineNumber(), 
     frame.getColumnNumber()); 
    }; 
    }; // END. stack trace 

Dieses Programm ausführen, und wir erhalten die folgende Ausgabe:

/home/ray/dev/test/error.js:57:9 
    foo() 
^
Error: `foo` has been removed in favorof `bar` 
    at function() (/home/ray/dev/test/error.js:53:3) 
    at b() (domain.js:183:18) 
    at Domain.run() (domain.js:123:23) 
    at function() (/home/ray/dev/test/error.js:52:3) 
    at Module._compile() (module.js:456:26) 
    at Module._extensions..js() (module.js:474:10) 
    at Module.load() (module.js:356:32) 
    at Module._load() (module.js:312:12) 
    at Module.runMain() (module.js:497:10)