Одно из решений, это введение дебаг мода для приложения на JS. Идея такая, что если дебаг мод установлен в false, ошибки происходят сами собой, если же дебаг мод true - ошибки могут логироваться на сервере или алертом показывать свое присутствие с указанием строки и причины ошибки. Очень полезно для IE.
Пример:
function doSomething(value){Идея примера такова, что если возникла ошибка, то в зависимости от установленного дебаг мода ошибка или логируется или просто показывается. Сейчас, я постараюсь объяснить всю уязвимость данной идеи.
try {
process(value);
} catch (ex){
if (debugMode){
throw ex;
} else {
log(1, "doSomething(): " + ex.message);
}
}
}
Если ошибка возникнет в функции process(), она будет перехвачена в функции doSomething() и в зависимости от дебаг мода сгенерируется или залогируется, тем самым разрушит call stack. Ошибка будет слишком далека от актуального события, которое нам и нужно отдебажить. Вся полезная информация, которая могла бы быть решением будет утеряна, так как мы выйдем из функции process(). Используя этот код, ваш дебагер будет обрывать выполнение программы в строке содержащей throw ex, в то время как вы хотите оборвать выполнение в самой функции process().
Мое решение - это код, который будет скорее предотвращать полезный дебаг, чем разрешать его.
Есть два способа решения этой проблемы:
1 (Галимый):
function doSomething(value){2 (Нормальный):
if (!debugMode){
process(value);
} else {
try {
process(value);
} catch (ex){
log(1, "doSomething(): " + ex.message);
}
}
}
var doSomething = debugMode ?Второй метод более предпочтительнее, так как он предотвращает проверку дебаг мода каждый раз, когда функция исполняется. Еще его легче автоматизировать. Предполагается, что у вас есть один или несколько обьектов и вы хотите, что бы все их методы имели враппер для отлова ошибок на продакшине. Вот вам пример такого кода:
function(value){
process(value);
} :
function(value){
try {
process(value);
} catch (ex){
log(1, "doSomething(): " + ex.message);
}
};
Пример:
//by Nicholas C. Zakas (MIT Licensed)Этот код пробегает по всем методам объекта и заменяет его функции на другие, которые уже содержат в себе механизм отлова ошибок. Вот пример использования:
function productionize(object){
var name,
method;
for (name in object){
method = object[name];
if (typeof method == "function"){
object[name] = function(name, method){
return function(){
try {
return method.apply(this, arguments);
} catch (ex) {
log(1, name + "(): " + ex.message);
}
};
}(name, method);
}
}
}
var system = {Всегда убеждайтесь в том, что ошибка сгенерировалась именно там где нужно - это первая проблема дебага JS ошибок. Удачи!
fail: function(){
throw new Error("Oops!");
}
};
function log(severity, message){
alert(severity + ":" + message);
}
if (!debugMode){
productionize(system);
}
system.fail(); //error is trapped!
По материалам: Nicholas C. Zakas