Отслеживание исходной строки ошибки в Javascript Eval - PullRequest
16 голосов
/ 20 августа 2010

Я создаю что-то, что включает в себя javascripts на лету, что работает, но я стараюсь улучшить обнаружение ошибок (поэтому все ошибки не просто появляются из какой-то строки рядом с вызовом AJAX, который тянет их вниз.

Если я использую eval для оценки многострочного файла JavaScript, есть ли способ отследить, на какой строке произошла ошибка?

Сохраняя ссылки на нужные мне переменные, у меня нет проблем с определением, в каком файле произошла ошибка. Моя проблема заключается в определении, в какой строке произошла ошибка.

Пример:

try {
  eval("var valid_statement = 7; \n invalid_statement())))");
} catch(e) {
  var err = new Error();
  err.message = 'Error in Evald Script: ' + e.message;
  err.lineNumber = ???
  throw err;
}

Как я могу сказать, что там произошла ошибка во второй строке? В частности, я заинтересован в том, чтобы сделать это в Firefox.

Я знаю, что объекты ошибок имеют e.stack в браузерах Mozilla, но вывод, похоже, не учитывает символы новой строки должным образом.

Ответы [ 3 ]

8 голосов
/ 21 августа 2010
  • Номер строки в уклоненном скрипте начинается с того, который включен eval.
  • Объект ошибки имеет номер строки, на которой он был создан.

Так что-то вроде ...

try {
  eval('var valid_statement = 7; \n invalid_statement())))');
} catch(e) {
  var err = e.constructor('Error in Evaled Script: ' + e.message);
  // +3 because `err` has the line number of the `eval` line plus two.
  err.lineNumber = e.lineNumber - err.lineNumber + 3;
  throw err;
}
4 голосов
/ 14 ноября 2014

Глобальный прослушиватель событий ошибок поймает исключение из eval и покажет правильные номера строк (возможно, не во всех браузерах):

window.addEventListener('error', function(e) {
    console.log(e.message
        , '\n', e.filename, ':', e.lineno, (e.colno ? ':' + e.colno : '')
        , e.error && e.error.stack ? '\n' : '', e.error ? e.error.stack : undefined
    );
}, false);
1 голос
/ 26 июля 2013

Не думаю, что вы можете сделать это с помощью eval надежно. Однако вы можете сделать это вместо eval:

try {
    $("<script />").html(scriptSource).appendTo("head").remove();
} catch (e) {
    alert(e.lineNumber);
}
...