如何捕捉Javascript腳本錯(cuò)誤并記錄到日志中?
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
一、xml httprequest和xml dom基礎(chǔ) 這兩個(gè)是web 開(kāi)發(fā)的常用東西,就不說(shuō)了,先看看使用:
二、javascript腳本錯(cuò)誤處理基礎(chǔ)
請(qǐng)教大家一個(gè)問(wèn)題?如何處理腳本錯(cuò)誤的?又如何去捕捉腳本錯(cuò)誤的?有沒(méi)有遇到過(guò)客戶打電話抱怨系統(tǒng)不能運(yùn)行,而你判斷可能是客戶端問(wèn)題后就不知道如何處理的情況? 最新的瀏覽器都支持try/catch方式捕捉javascript異常,還有一個(gè)onerror事件來(lái)處理異常。
三、將客戶端錯(cuò)誤寫(xiě)入服務(wù)器端的日志文件 首先,客戶端建立一個(gè)單例模式的對(duì)象logger // singleton class constructor function logger() { // fields this.req;
// methods this.errortoxml = errortoxml; this.log = log; } 其次,我們要把javascript錯(cuò)誤序列化到xml對(duì)象中。默認(rèn)情況下,error對(duì)象只有兩個(gè)屬性:name和message。我們需要再建立一個(gè)屬性:location。 // map an error to an xml document function errortoxml(err) { var xml = '<?xml version="1.0"?>\n' + '<error>\n' + '<name>' + err.name + '</name>\n' + '<message>' + err.message + '</message>\n'; if (err.location) xml += '<location>' + err.location + '</location>'; xml += '</error>'; return xml; } 接下來(lái)是利用xmlhttp請(qǐng)求將錯(cuò)誤信息寫(xiě)入到日志中,原文作者利用cgi寫(xiě)入,這里,可以根據(jù)具體的應(yīng)用情況選擇大家自己的處理方式: // log method of logger class function log(err) { // feature sniff if (window.xmlhttprequest) this.req = new xmlhttprequest(); else if (window.activexobject) this.req = new activexobject("microsoft.xmlhttp"); else return; // throw up our hands in despair // set the method and uri this.req.open("post", "/cgi-bin/ajaxlogger.cgi"); // set the request headers. referer will be the top-level // uri which may differ from the location of the error if // it occurs in an included .js file this.req.setrequestheader('referer', location.href); this.req.setrequestheader('content-type', 'text/xml'); // function to be called when the request is complete this.req.onreadystatechange = errorlogged; this.req.send(this.errortoxml(err)); // if the request doesn't complete in 10 seconds, // something is up this.timeout = window.settimeout("abortlog();", 10000); } 然后,我們要實(shí)例化這個(gè)類: // should only be one instance of the logger var logger = new logger(); 最后的兩個(gè)方法用來(lái)做“家務(wù)管理”的。 // we tried, but if there is a connection error, it is hopeless function abortlog() { logger.req.abort(); alert("attempt to log the error timed out."); }
// called when the state of the request changes function errorlogged() { if (logger.req.readystate != 4) return; window.cleartimeout(logger.timeout); // request completed if (logger.req.status >= 400) alert('attempt to log the error failed.'); }
好了,把前面講述的幾個(gè)方法封裝到一個(gè)公用腳本logger.js中去吧,然后你就可以enjoy了。
在自己開(kāi)發(fā)的腳本中引入這個(gè)js并使用如下: 【stone評(píng)】有問(wèn)題,有興趣者可調(diào)整。 <script type="text/javascript" src="logger.js"></script> <script type="text/javascript"> function traperror(msg, uri, ln) { // wrap our unknown error condition in an object var error = new error(msg); error.location = uri + ', line: ' + ln; // add custom property logger.log(error); warnuser(); return true; // stop the yellow triangle } window.onerror = traperror;
function foo() { try { riskyoperation(); } catch (err) { // add custom property err.location = location.href + ', function: foo()'; logger.log(err); warnuser(); } } function warnuser() { alert("an error has occurred while processing this page."+ "our engineers have been alerted!"); // drastic action location.href = '/path/to/error/page.html'; } </script>
最后是在服務(wù)器端利用cgi寫(xiě)入日志,代碼如下,喜歡用別的方式的程序員可以選擇利用你們擅長(zhǎng)的語(yǔ)言來(lái)將xml日志信息寫(xiě)入服務(wù)器端文件。 use cgi; use cgi::carp qw(set_progname); use xml::simple; my $request = cgi->new();
my $method = $request->request_method(); # method must be post if ($method eq 'post') { eval { my $content_type = $request->content_type(); if ($content_type eq 'text/xml') { print $request->header(-status => '415 unsupported media type', -type => 'text/xml'); croak "invalid content type: $content_type\n"; } # when method is post and the content type is neither # uri encoded nor multipart form, the entire post # is stuffed into one param: postdata my $error_xml = $request->param('postdata'); my $ref = xml::simple::xmlin($error_xml); my ($name, $msg, $location) = ($ref->{'name'}, $ref->{'message'}, ''); $location = $ref->{'location'} if (defined($ref->{'location'})); # this will change the name of the carper in the log set_progname('client-side error'); my $remote_host = $request->remote_host(); carp "name: [$name], msg: [$msg], location: [$location]"; }; if ($@) { print $request->header(-status => '500 internal server error', -type => 'text/xml'); croak "error while logging: $@"; } else { # this response code indicates that the operation was a # success, but the client should not expect any content print $request->header(-status => '204 no content', -type => 'text/xml'); } } else { print $request->header(-status => '405 method not supported', -type => 'text/xml'); croak "unsupported method: $method"; } 該文章在 2010/8/13 8:24:27 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |