在Web开发中,服务器端的错误处理是一个常见的话题。例如,在使用ASP.NET MVC时,可以通过继承基控制器来实现异常处理逻辑,或者在Global.asax文件中使用Application_Error方法。但是,客户端的错误处理同样重要。希望记录这些错误,并提供有关错误发生位置(文件名、行号和列号)、堆栈跟踪等信息。本文将介绍如何在AngularJS框架中实现客户端错误日志记录,并解决生产环境中的代码压缩和打包问题。
首先,需要通过$exceptionHandler服务订阅所有异常。这可以通过简单地覆盖默认的$exceptionHandler服务来实现。以下是一个示例代码:
(function () {
angular.module('app').factory('$exceptionHandler', [
'$log', '$window', function ($log, $window) {
function error(exception, cause) {
$log.error.apply($log, arguments);
try {
var errorMessage = exception.toString();
var stackTrace = printStackTrace({ e: exception });
$.ajax({
type: "POST",
url: "/logger",
contentType: "application/json",
data: angular.toJson({
url: $window.location.href,
message: errorMessage,
type: "exception",
stackTrace: stackTrace,
cause: cause
})
});
} catch (loggingError) {
$log.warn("Error server-side logging failed");
$log.log(loggingError);
}
}
return error;
}]);
})();
在这段代码中,通过printStackTrace方法获取错误堆栈跟踪,然后将所有错误信息发送到服务器端进行存储。但是,在生产环境中,通常会使用代码压缩和打包,这会导致堆栈跟踪中的文件名和行号信息发生变化,从而失去实际错误位置。
为了解决这个问题,需要执行以下两个操作: 1. 创建与打包文件对应的.map文件,以建立打包文件与原始文件之间的映射关系。 2. 使用StackTrace-gps.js库,根据打包文件中的信息查找实际的错误位置。
以下是一个示例代码,展示了如何在生产环境中实现错误日志记录:
(function () {
angular.module('app').factory('$exceptionHandler', [
'$log', '$window', function ($log, $window) {
function error(exception, cause) {
$log.error.apply($log, arguments);
try {
var errorMessage = exception.toString();
var stackTrace = printStackTrace({ e: exception });
var locationWithLineAndColumn = stackTrace[0].substr(stackTrace[0].indexOf('http'));
var array = locationWithLineAndColumn.split(':');
var columnNumber = array[array.length - 1];
var lineNumber = array[array.length - 2];
var location = locationWithLineAndColumn.substr(0, locationWithLineAndColumn.length - 2 - lineNumber.length - columnNumber.length);
var stackframe = new StackFrame(undefined, [], location, parseInt(lineNumber), parseInt(columnNumber));
new StackTraceGPS().pinpoint(stackframe).then(
function (answer) {
stackTrace.unshift(answer.fileName + ':' + answer.lineNumber + ':' + answer.columnNumber);
$.ajax({
type: "POST",
url: "/logger",
contentType: "application/json",
data: angular.toJson({
url: $window.location.href,
message: errorMessage,
type: "exception",
stackTrace: stackTrace,
functionName: answer.functionName,
cause: cause
})
});
},
function (answer) {
$log.warn("Error server-side logging failed");
console.log(answer);
}
);
} catch (loggingError) {
$log.warn("Error server-side logging failed");
$log.log(loggingError);
}
}
return error;
}]);
})();
在这段代码中,首先获取错误堆栈跟踪的第一个元素,然后解析出打包文件的URL和错误位置(行号和列号)。接下来,使用StackTraceGPS库的pinpoint方法,根据这些信息查找实际的错误位置。