基於上一篇提到的在前端紀錄 log 會有個問題
如果拋出錯的程式碼沒有用 try catch 包起來就無法紀錄 log
AngularJS 提供了 $exceptionHandler 這個好用的東西
在 「Angular 世界」中可以攔截到任何 uncaught exception
官方提供的 Sample Code 和 Documentation 其實非常清楚
連模組都幫你寫好了, 下載回來再把模組依賴進去就可以使用了
根本懶人包, 感覺底下就有人會回 「你媽知道你在這邊發廢文嗎 ?」
如果你只求安裝施工及如何使用的話其實看到這裡就不用繼續往下看
官方提供的 logToServer.js 的代碼是直接覆寫掉 $log 跟 $exceptionHandler
可以用 decorator 方法去攔截並擴充
這種修飾子的做法我覺得非常棒, 可以在不影響原有的功能下去擴充功能
改寫 $log 跟 $exceptionHandler 的部分如下 :
logToServerProvide.$inject = ['$provide'];
logDecorator.$inject = ['$delegate'];
exceptionDecorator.$inject = ['$delegate'];
function logToServerProvide($provide) {
$provide.decorator('$log', logDecorator);
$provide.decorator('$exceptionHandler', exceptionDecorator);
}
function logDecorator($delegate) {
var origLog = $delegate.log;
var origInfo = $delegate.info;
var origDebug = $delegate.debug;
var origWarn = $delegate.warn;
var origError = $delegate.error;
$delegate.log = function (msg) {
JL().trace(msg);
origLog.call(null, msg)
};
$delegate.info = function (msg) {
JL().info(msg);
origInfo.call(null, msg)
};
$delegate.debug = function (msg) {
JL().debug(msg);
origDebug.call(null, msg)
};
$delegate.warn = function (msg) {
JL().warn(msg);
origWarn.call(null, msg)
};
$delegate.error = function (msg) {
JL().error(msg);
origError.call(null, msg)
};
return $delegate;
}
function exceptionDecorator($delegate) {
return function (exception, cause) {
$delegate(exception, cause);
JL().fatalException(cause, exception);
};
}
angular.module('logToServer', [])
.config(logToServerProvide)
至於 Interceptor 的部分跟 AOP 概念一致
並不會影響原本的流程只是多掛上一個攔截器去處理 log
也是一個非常漂亮的設計跟寫法
範例一樣是接續之前放在 GitHub 上的 JSNLogWithNet
參考文章 :
- Enhancing AngularJS Logging using Decorators
- stack overflow - How to override $exceptionHandler implementation
- [AngularJs]淺談Angular.js的Provider機制
- AngularJs Exception Handling
後記 :
不知道有沒有人遇到跟我一樣的問題 ?
預設 JL().trace() Method 是不會打到後端
就算改了 ajaxAppender level 也無法打去後端
angular.module('logToServer', [])
.service('$log', function () {
this.log = function (msg) {
JL('Angular').trace(msg); // not send to back-end
}
this.debug = function (msg) {
JL('Angular').debug(msg);
}
this.info = function (msg) {
JL('Angular').info(msg);
}
this.warn = function (msg) {
JL('Angular').warn(msg);
}
this.error = function (msg) {
JL('Angular').error(msg);
}
})