Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   генерация и логирование ошибки (https://javascript.ru/forum/misc/46253-generaciya-i-logirovanie-oshibki.html)

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

Цитата:

Сообщение от Hapson
Как бы такое сделать?

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

Hapson 03.04.2014 10:47

Цитата:

Сообщение от ksa (Сообщение 305784)
Все, что есть...
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

Цитата:

Сообщение от Sweet
Есть некроссбраузерный вариант:

В том-то и дело, что не кроссбраузерный.
В 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

Цитата:

Сообщение от dmitry111 (Сообщение 305807)
в случае ошибки на клиенте скрипт не перестает работать

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

danik.js 03.04.2014 12:54

dmitry111, он же php'шник, он наверно и не знает что в браузерах встрена консоль ошибок )

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

dmitry111 03.04.2014 12:54

Цитата:

Сообщение от nice_try
смотря какие ошибки

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

Hapson 03.04.2014 13:41

dmitry111,
Моя ошибка - не написал для чего все это.
Для того чтобы отправить сведения об ошибке на сервер для логирования.
То есть я пишу в коде triggerError('ошибка!') и все. Дальше я хочу чтобы эта функция передала на сервер не только текст ошибки, но и файл/строку, где была вызвана.
Цитата:

Сообщение от dmitry111
он наверно и не знает что в браузерах встрена консоль ошибок

смешно, смешно... :)
Цитата:

Сообщение от dmitry111
Мне ее как раз и не хватает при работе с сервером

плагин для NPP + плагин для FF/Chrome = пошаговое выполнение php с просмотром переменных в консоли NPP

dmitry111 03.04.2014 14:07

думаю вам сюда

http://javascript.ru/blog/azriman/se...bok-javascript

nerv_ 03.04.2014 14:26

Hapson, тебе не ошибки нужны, а пользовательские события. Можешь использовать
Цитата:

Сообщение от Octane
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

Цитата:

Сообщение от Hapson
getXHR

ты чо для IE6 чтоли делаешь?

Hapson 03.04.2014 14:37

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

Hapson 03.04.2014 14:39

Цитата:

Сообщение от Octane (Сообщение 305836)
ты чо для IE6 чтоли делаешь?

Пусть будет... несколько лишних строчек - не страшно

nerv_ 03.04.2014 14:44

Цитата:

Сообщение от Hapson
Я не хочу оборачивать этот участок кода в try...catch, ради того чтобы в try по условию бросить исключение.

не поймаешь
try {
    setTimeout(function() {
        foo();
    }, 1000)
} catch(e) {
    alert(1); // will not work
}

window.onerror = function(e) {
    alert(2);
};

Цитата:

Сообщение от Hapson
Я хочу просто вызвать некий 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

Цитата:

Сообщение от nerv_
ща америку для тебя открою:

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

nerv_ 03.04.2014 15:06

Цитата:

Сообщение от Hapson
ООП? какой к черту ООП - это javascript. Здесь нет никаких ООП, есть только закос под ООП

"php головного мозга" детектед :)

твою реализацию можно сломать одной строчкой
window.onerror = null;

Удачного дебага.

Hapson 03.04.2014 15:22

Цитата:

Сообщение от nerv_
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

Цитата:

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

ты тут такие глупости больше не пиши

dmitry111 03.04.2014 15:52

Цитата:

Сообщение от Hapson
ООП? какой к черту ООП - это javascript. Здесь нет никаких ООП, есть только закос под ООП

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

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

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

dmitry111 03.04.2014 16:01

Цитата:

Сообщение от Octane
Ни Chrome, ни IE не добавляют в new Error информацию о строке и файле, только в фаерфоксе норм:


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

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

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

Octane 03.04.2014 16:05

Цитата:

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

Мне не зачем, просто интересно было, как это реализовать

Hapson 03.04.2014 16:24

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

dmitry111 03.04.2014 16:55

Цитата:

Сообщение от Hapson
Как сделать так, чтобы функция при вызове узнавала, в каком файле и на какой строке ее вызвали.

скрипты для уменьшения их веса принято сжимать и минимизировать в один файл. Наверное поэтому определение файла и строки теряет актуальность в 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


Часовой пояс GMT +3, время: 03:33.