Вход

Просмотр полной версии : генерация и логирование ошибки


Hapson
03.04.2014, 09:51
Кто знаком с php, тот знает, что там есть замечательная функция trigger_error('my error'). Функция генерирует пользовательскую ошибку: E_USER_NOTICE/WARNING/ERROR.
Если определен собственный обработчик ошибок, то все это вместе позволяет в удобном виде логировать ошибки скрипта, а также свои ошибки. Например

<?php
if(/* что-то пошло не так */){
trigger_error('текст ошибки');
}
?>

В обработчике ошибок ловим саму ошибку, имя файла и номер строки, где произошла ошибка. Ну и там же доступен контекст и трассировка.
При генерации такой ошибки скрипт не останавливается - это не исключение.

На js я переопределил window.onerror и написал функцию логирования ошибок на сервере. Так вот интересует вопрос, как в js реализовать аналог trigger_error из php.
То есть чтобы можно было сгенерировать ошибку, но не останавливать выполнение. А в обработчике ошибок хотелось бы помимо текста ошибки узнать файл и номер строки, где произошла ошибка. Ну и естественно при генерации ошибки хочется указать только текст ошибки, а передачу имени файла и номера строки возложить на плечи функции.

Как бы такое сделать?

ksa
03.04.2014, 10:37
Как бы такое сделать?
Все, что есть...
http://javascript.ru/try-catch

Hapson
03.04.2014, 10:47
Все, что есть...
http://javascript.ru/try-catch

Некошерно оборачивать каждую генерацию ошибки в try...catch.
Я думаю, что нужно как-то унаследовать стандартный Error, но чтобы номер строки и файл были приведены к единому виду независимо от браузера.
И тогда можно будет просто делать
triggerError(new UserError('текст ошибки'));

Sweet
03.04.2014, 10:58
Есть некроссбраузерный вариант:
alert( (new Error).stack )

Hapson
03.04.2014, 11:06
Есть некроссбраузерный вариант:
В том-то и дело, что не кроссбраузерный.
В FF есть lineNumber и fileName, в IE теже свойства зовутся иначе, в хроме вообще непонятно что. А еще ведь есть куча браузеров...
window.onerror ведь ловит файл и строку. Вот нужно тоже самое, только без генерации реальной ошибки, которая остановит скрипт. Нужно кроссбраузерно получить файл и строку, где был создан объект Error

Octane
03.04.2014, 11:58
Думал прокатит, но чот нигде не заработало, хотя CustomEvent нормально диспатчится, а ErrorEvent не хочет :(
window.addEventListener("error", function (event) {
console.log(event);
});

function triggerError(error) {
var event = new ErrorEvent(error.message, {
lineno: error.lineNumber,
filename: error.fileName
});
window.dispatchEvent(event);
}

triggerError(new Error("test error"));

dmitry111
03.04.2014, 12:27
в случае ошибки на клиенте скрипт не перестает работать, а консоль браузера вывалит ошибку. Там вам и текст ошибки и файл и номер строки - все есть.

Вам этой информации недостаточно или я чего-то не понимаю?

nice_try
03.04.2014, 12:46
в случае ошибки на клиенте скрипт не перестает работать

смотря какие ошибки

danik.js
03.04.2014, 12:54
dmitry111, он же php'шник, он наверно и не знает что в браузерах встрена консоль ошибок )

Мне ее как раз и не хватает при работе с сервером. Есть конечно и для серверов отладчики, но они какие-то кривые.

dmitry111
03.04.2014, 12:54
смотря какие ошибки

речь о том, что процесс не падает, в отличии от сервера

Hapson
03.04.2014, 13:41
dmitry111,
Моя ошибка - не написал для чего все это.
Для того чтобы отправить сведения об ошибке на сервер для логирования.
То есть я пишу в коде triggerError('ошибка!') и все. Дальше я хочу чтобы эта функция передала на сервер не только текст ошибки, но и файл/строку, где была вызвана.
он наверно и не знает что в браузерах встрена консоль ошибок
смешно, смешно... :)
Мне ее как раз и не хватает при работе с сервером
плагин для NPP + плагин для FF/Chrome = пошаговое выполнение php с просмотром переменных в консоли NPP

dmitry111
03.04.2014, 14:07
думаю вам сюда

http://javascript.ru/blog/azriman/servernoe-logirovanie-klientskih-oshibok-javascript

nerv_
03.04.2014, 14:26
Hapson, тебе не ошибки нужны, а пользовательские события. Можешь использовать CustomEvent, а можешь написать свою реализацию.

Observer, CustomEvent, ...

Octane
03.04.2014, 14:29
dmitry111, передать не проблема, тема о trigger_event, проблема в том, что dispatchить свою ошибку не получается.

Hapson
03.04.2014, 14:31
dmitry111,
я уже переопределил window.onerror и написал функционал отправки/логирования. Теперь нужно написать функцию-аналог trigger_error из php.
Вот что есть

(function(){window.onerror = ErrorHandler;

/*** SETTING ***/
var url = window.location.protocol +"//"+ window.location.hostname +"/phpHandlerJSError.php";
var debug = true;
var serverLog = true;

function ErrorHandler(message, file, line){
if(!!serverLog){sendError(message, file, line);}
return !!debug ? false : true;
}

function sendError(message, file, line){
var xhr = getXHR();
var param = "message="+ encodeURIComponent(message) +"&";
param += "file="+ encodeURIComponent(file) +"&";
param += "line="+ encodeURIComponent(line);
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("HTTP_X_FORWARDED_FOR", "XmlHttpRequest");
/* tmp */
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText);
}
};
xhr.send(param);
}

function getXHR(){
try{return new XMLHttpRequest();}catch(e){}
try{return new ActiveXObject("Msxml2.XMLHTTP.3.0");}catch(er){}
throw new Error("This browser does not support XMLHttpRequest");
}

}());

При ошибке сработает ErrorHandler. В дополнение к этому нужна функция, которая будет сама узнавать в каком файле и на какой строке ее вызвали. То есть, в каком-то участке кода я ожидаю, что что-то может пойти не так. Я не хочу оборачивать этот участок кода в try...catch, ради того чтобы в try по условию бросить исключение.
Я хочу просто вызвать некий triggerError('ошибка') и продолжить выполнение. triggerError должен определить файл и строку, где его вызвали и вместе с ошибкой передаст это все в ErrorHandler, который и отправит все это на сервер

Octane
03.04.2014, 14:34
getXHR
ты чо для IE6 чтоли делаешь?

Hapson
03.04.2014, 14:37
nerv_,
что-то я не догоню, как при помощи observer такое реализовать..?

Hapson
03.04.2014, 14:39
ты чо для IE6 чтоли делаешь?
Пусть будет... несколько лишних строчек - не страшно

nerv_
03.04.2014, 14:44
Я не хочу оборачивать этот участок кода в try...catch, ради того чтобы в try по условию бросить исключение.
не поймаешь
try {
setTimeout(function() {
foo();
}, 1000)
} catch(e) {
alert(1); // will not work
}

window.onerror = function(e) {
alert(2);
};
Я хочу просто вызвать некий triggerError('ошибка') и продолжить выполнение
см. мой ответ выше

Octane, он просто ерундой страдает :) Не хочет слушать, что советуют)

Hapson, ща америку для тебя открою:
var app = {
error: function(e) {
alert(1)
}
};

app.error();
Читай про ООП.

Hapson
03.04.2014, 15:02
nerv_,
Пиши по делу, ладно?
Мне нужно, чтобы при вызове определенной функции, эта функция узнала, в каком файле и на какой строке ее вызвали.
В php это выглядит так

<?php
function ErrorHandler($number, $message, $file, $line, $context){
/* обработка ошибки */
}
set_error_handler('ErrorHandler');

// и теперь...

trigger_error('ошибка');
// в ErrorHandler будет передан текст ошибки, файл и строка, где был вызван trigger_error, код ошибки и контекст.
?>

Hapson
03.04.2014, 15:05
ща америку для тебя открою:
вообще ни о чем не говорит.
ООП? какой к черту ООП - это javascript. Здесь нет никаких ООП, есть только закос под ООП

nerv_
03.04.2014, 15:06
ООП? какой к черту ООП - это javascript. Здесь нет никаких ООП, есть только закос под ООП
"php головного мозга" детектед :)

твою реализацию (http://javascript.ru/forum/misc/46253-generaciya-i-logirovanie-oshibki-2.html#post305835) можно сломать одной строчкой
window.onerror = null;
Удачного дебага.

Hapson
03.04.2014, 15:22
window.onerror = null
есть другие способы?

Вопрос в другом - как сделать аналог trigger_error

Octane
03.04.2014, 15:48
Ни Chrome, ни IE не добавляют в new Error информацию о строке и файле, только в фаерфоксе норм:
window.addEventListener("error", function (event) {
alert(event);
});

function triggerError(error) {
var event;
try {
event = document.createEvent("ErrorEvent");
}
catch (reason) {
event = document.createEvent("Event");
}
if (event.initErrorEvent) {
event.initErrorEvent("error", false, false, error.message, error.fileName, error.lineNumber);
}
else {
event.initEvent("error", false, false);
event.message = error.message;
event.filename = error.fileName;
event.lineno = error.lineNumber;
}
event.stack = error.stack;
window.dispatchEvent(event);
}

triggerError(new Error("test error"));Проверял в Chrome 35, Aurora 30 и IE11

какой к черту ООП - это javascript. Здесь нет никаких ООП, есть только закос под ООП
ты тут такие глупости больше не пиши

dmitry111
03.04.2014, 15:52
ООП? какой к черту ООП - это javascript. Здесь нет никаких ООП, есть только закос под ООП

вот это вот очень неверное суждение, которым иногда злоупотребляют php-шники

Даже если в js чего-то нет (например Классов), то никто не мешает вам это реализовать самому!

js - это полноценный объектно-ориентированный язык!

dmitry111
03.04.2014, 16:01
Ни Chrome, ни IE не добавляют в new Error информацию о строке и файле, только в фаерфоксе норм:


кроссбраузерные только:
Error.prototype.message
Error.prototype.name

Зачем строка?
А если весь скрипт в одну строку будет?

Можно ставить переменные-метки в частях кода и передавать эти метки в случае ошибки

Octane
03.04.2014, 16:05
Зачем строка?
А если весь скрипт в одну строку будет?
Мне не зачем, просто интересно было, как это реализовать

Hapson
03.04.2014, 16:24
dmitry111,
Вопрос не в том "зачем", а КАК.
Как сделать так, чтобы функция при вызове узнавала, в каком файле и на какой строке ее вызвали.

dmitry111
03.04.2014, 16:55
Как сделать так, чтобы функция при вызове узнавала, в каком файле и на какой строке ее вызвали.

скрипты для уменьшения их веса принято сжимать и минимизировать в один файл. Наверное поэтому определение файла и строки теряет актуальность в js.


Можно вместо строки передавать с ошибкой ее номер и основываться на нем.

kostyanet
03.04.2014, 16:55
У кого php головного мозга тот должен понимать что номер строки скрипта и имя файла может быть взято из html в котором любой скрипт чуйствует себя как domа.

Это не считая таких форматов как инлайновые скрипты.

Файл скрипта и номер строки в этом файле в JS это _частный_ случай. Хочет браузер показать - покажет, не хочет - не покажет.

WScript даже номер символа демонстрирует. Ну и что?

kostyanet
03.04.2014, 17:12
Кстати, ошибки в скриптах под GM старый фаерфокс показывал как ошибки самого скрипта GM. В бытность error console еще.

kostyanet
03.04.2014, 17:20
stackoverflow.com/questions/2343343/how-can-i-determine-the-current-line-number-in-javascript