±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚ²©¿Í
,±¾ÎÄ·ÖÏíÁËǰ¶ËÒì³£¼à¿ØÖÐÐèÒªÁ˽âµÄÒì³£²¶»ñÓëÉϱ¨»úÖÆµÄһЩҪµã£¬Í¬Ê±°üº¬ÁËʵսÐÔÖʵIJο¼´úÂëºÍÁ÷³Ì¡£ |
|
ǰÑÔ
Ê×ÏÈ£¬ÎÒÃÇΪʲôҪ½øÐÐÒì³£²¶»ñºÍÉϱ¨ÄØ£¿
ÕýËùν°ÙÃÜÒ»Ê裬һ¸ö¾¹ýÁË´óÁ¿²âÊÔ¼°Áªµ÷µÄÏîÄ¿ÔÚÓÐЩʱºò»¹ÊÇ»áÓÐÊ®·ÖÒþ±ÎµÄbug´æÔÚ£¬ÕâÖÖ¸´ÔÓ¶øÓÖ²»¿ÉÔ¤¼ûÐÔµÄÎÊÌâΨÓÐͨ¹ýÍêÉÆµÄ¼à¿Ø»úÖÆ²ÅÄÜÓÐЧµÄ¼õÉÙÆä´øÀ´µÄËðʧ£¬Òò´Ë¶ÔÓÚÖ±ÃæÓû§µÄǰ¶Ë¶øÑÔ£¬Òì³£²¶»ñÓëÉϱ¨ÊÇÖÁ¹ØÖØÒªµÄ¡£
ËäȻĿǰÊÐÃæÉÏÒѾÓÐһЩ·Ç³£ÍêÉÆµÄǰ¶Ë¼à¿ØÏµÍ³´æÔÚ£¬Èçsentry¡¢bugsnagµÈ£¬µ«ÊÇÖª¼ºÖª±Ë£¬²ÅÄܰÙÕ½²»´ù£¬Î¨ÓÐÁ˽âÔÀí£¬ÃþÇåÂß¼£¬Ê¹ÓÃÆðÀ´²ÅÄܵÃÐÄÓ¦ÊÖ¡£
Òì³£²¶»ñ·½·¨
1. try catch
ͨ³££¬ÎªÁËÅжÏÒ»¶Î´úÂëÖÐÊÇ·ñ´æÔÚÒì³££¬ÎÒÃÇ»áÕâһд£º
<table
width="60%" border="0" align="center"
cellpadding="7" cellspacing="1"
bgcolor="#CCCCCC" class="content">
<tr >
<td height="25" bgcolor="#f5f5f5"
id="dai">
<p style="text-indent: 0em;">Hello
World!</p></td>
</tr>
</table> |
ʹÓÃtry catchÄܹ»ºÜºÃµÄ²¶»ñÒì³£²¢¶ÔÓ¦½øÐÐÏàÓ¦´¦Àí£¬²»ÖÁÓÚÈÃÒ³Ãæ¹Òµô£¬µ«ÊÇÆä´æÔÚһЩ±×¶Ë£¬±ÈÈçÐèÒªÔÚ²¶»ñÒì³£µÄ´úÂëÉϽøÐаü¹ü£¬»áµ¼ÖÂÒ³ÃæÓ·Öײ»¿°£¬²»ÊÊÓÃÓÚÕû¸öÏîÄ¿µÄÒì³£²¶»ñ¡£
2. window.onerror
Ïà±Ètry catchÀ´Ëµwindow.onerrorÌṩÁËÈ«¾Ö¼àÌýÒì³£µÄ¹¦ÄÜ£º
window.onerror
= function(errorMessage, scriptURI, lineNo,
columnNo, error) {
console.log('errorMessage: ' + errorMessage);
// Òì³£ÐÅÏ¢
console.log('scriptURI: ' + scriptURI); // Òì³£Îļþ·¾¶
console.log('lineNo: ' + lineNo); // Òì³£ÐкÅ
console.log('columnNo: ' + columnNo); // Òì³£ÁкÅ
console.log('error: ' + error); // Òì³£¶ÑÕ»ÐÅÏ¢
};
console.log(a); |
Èçͼ£º

window.onerror¼´ÌṩÁËÎÒÃÇ´íÎóµÄÐÅÏ¢£¬»¹ÌṩÁË´íÎóÐÐÁкţ¬¿ÉÒÔ¾«×¼µÄ½øÐж¨Î»£¬Èç´ËËÆºõÕýÊÇÎÒÃÇÏëÒªµÄ£¬µ«ÊǽÓÏÂÀ´±ãÊÇÌî¿Ó¹ý³Ì¡£
Òì³£²¶»ñÎÊÌâ
1. Script error.
ÎÒÃǺϺõÇéÀíµØÔÚ±¾µØÒ³Ãæ½øÐг¢ÊÔ²¶»ñÒì³££¬È磺
<!--
http://localhost:3031/ -->
<script>
window.onerror = function() {
console.log(arguments);
};
</script>
<script src="http://cdn.xxx.com/index.js"></script> |
ÕâÀïÎÒÃǰѾ²Ì¬×ÊÔ´·Åµ½ÒìÓòÉϽøÐÐÓÅ»¯¼ÓÔØ£¬µ«ÊDz¶»ñµÄÒì³£ÐÅϢȴÊÇ£º

¾¹ý·ÖÎö·¢ÏÖ£¬¿çÓòÖ®ºówindow.onerrorÊÇÎÞ·¨²¶»ñÒì³£ÐÅÏ¢µÄ£¬ËùÒÔͳһ·µ»ØScript
error.£¬½â¾ö·½°¸±ãÊÇscriptÊôÐÔÅäÖà crossorigin="anonymous"
²¢ÇÒ·þÎñÆ÷Ìí¼ÓAccess-Control-Allow-Origin¡£
<script
src="http://cdn.xxx.com/index.js"
crossorigin="anonymous"></script> |
Ò»°ãµÄCDNÍøÕ¾¶¼»á½«Access-Control-Allow-OriginÅäÖÃΪ*£¬Òâ˼ÊÇËùÓÐÓò¶¼¿ÉÒÔ·ÃÎÊ¡£
2. sourceMap
½â¾ö¿çÓò»òÕß½«½Å±¾´æ·ÅÔÚͬÓòÖ®ºó£¬Äã¿ÉÄܻὫ´úÂëѹËõÒ»ÏÂÔÙ·¢²¼£¬Õâʱºò±ã³öÏÖÁËѹËõºóµÄ´úÂëÎÞ·¨ÕÒµ½Ôʼ±¨´íλÖõÄÎÊÌâ¡£Èçͼ£¬ÎÒÃÇÓÃwebpack½«´úÂë´ò°üѹËõ³Ébundle.js£º
//
webpack.config.js
var path = require('path');
// webpack 4.1.1
module.exports = {
mode: 'development',
entry: './client/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'client')
}
} |
×îºóÎÒÃÇÒ³ÃæÒýÈëµÄ½Å±¾ÎļþÊÇÕâÑùµÄ£º
!function(e){var
o={};function n(r){if(o[r])return o[r].exports;var
t=o[r]={i:r,l:!1,exports:{}}...; |
ËùÒÔÎÒÃÇ¿´µ½µÄÒì³£ÐÅÏ¢ÊÇÕâÑùµÄ£º

lineNo¿ÉÄÜÊÇÒ»¸ö·Ç³£Ð¡µÄÊý×Ö£¬Ò»°ãÊÇ1£¬¶øcolumnNo»áÊÇÒ»¸öºÜ´óµÄÊý×Ö£¬ÕâÀïÊÇ730£¬ÒòΪËùÓдúÂ붼ѹËõµ½ÁËÒ»ÐС£
ÄÇô¸ÃÈçºÎ½â¾öÄØ£¿´ÏÃ÷µÄͯЬ¿ÉÄÜÒѾ²Âµ½ÆôÓÃsource-mapÁË£¬Ã»´í£¬ÎÒÃÇÀûÓÃwebpack´ò°üѹËõºóÉú³ÉÒ»·Ý¶ÔÓ¦½Å±¾µÄmapÎļþ¾ÍÄܽøÐÐ×·×ÙÁË£¬ÔÚwebpackÖпªÆôsource-map¹¦ÄÜ£º
module.exports
= {
...
devtool: '#source-map',
...
} |
´ò°üѹËõµÄÎļþĩβ»á´øÉÏÕâÑùµÄ×¢ÊÍ£º
!function(e){var
o={};function n(r){if(o[r])return o[r].exports;var
t=o[r]={i:r,l:!1,exports:{}}...;
//# sourceMappingURL=bundle.js.map |
Òâ˼ÊǸÃÎļþ¶ÔÓ¦µÄmapÎļþΪbundle.js.map¡£ÏÂÃæ±ãÊÇÒ»¸ösource-mapÎļþµÄÄÚÈÝ£¬ÊÇÒ»¸öJSON¶ÔÏó£º
version:
3, // Source mapµÄ°æ±¾
sources: ["webpack:///webpack/bootstrap",
...], // ת»»Ç°µÄÎļþ
names: ["installedModules", "__webpack_require__",
...], // ת»»Ç°µÄËùÓбäÁ¿ÃûºÍÊôÐÔÃû
mappings: "aACA,IAAAA,KAGA,SAAAC...",
// ¼Ç¼λÖÃÐÅÏ¢µÄ×Ö·û´®
file: "bundle.js", // ת»»ºóµÄÎļþÃû
sourcesContent: ["// The module cache var
installedModules = {};..."], // Ô´´úÂë
sourceRoot: "" // ת»»Ç°µÄÎļþËùÔÚµÄĿ¼ |
Èç¹ûÄãÏëÏêϸÁË½â¹ØÓÚsourceMapµÄ֪ʶ£¬¿ÉÒÔǰÍù£ºJavaScript Source Map
Ïê½â
Èç´Ë£¬¼ÈÈ»ÎÒÃÇÄõ½Á˶ÔÓ¦½Å±¾µÄmapÎļþ£¬ÄÇôÎÒÃǸÃÈçºÎ½øÐнâÎö»ñȡѹËõǰÎļþµÄÒì³£ÐÅÏ¢ÄØ£¿Õâ¸öÎÒ»áÔÚÏÂÃæÒì³£Éϱ¨µÄʱºò½øÐнéÉÜ¡£
3. MVVM¿ò¼Ü
ÏÖÔÚÔ½À´Ô½¶àµÄÏîÄ¿¿ªÊ¼Ê¹ÓÃǰ¶Ë¿ò¼Ü£¬ÔÚMVVM¿ò¼ÜÖÐÈç¹ûÄãÒ»Èç¼ÈÍùµÄÏëʹÓÃwindow.onerrorÀ´²¶»ñÒì³££¬ÄÇôºÜ¿ÉÄÜ»áÖñÀº´òˮһ³¡¿Õ£¬»òÐí¸ù±¾²¶»ñ²»µ½£¬ÒòΪÄãµÄÒì³£ÐÅÏ¢±»¿ò¼Ü×ÔÉíµÄÒì³£»úÖÆ²¶»ñÁË¡£±ÈÈçVue
2.xÖÐÎÒÃÇÓ¦¸ÃÕâÑù²¶»ñÈ«¾ÖÒì³££º
Vue.config.errorHandler
= function (err, vm, info) {
let {
message, // Òì³£ÐÅÏ¢
name, // Òì³£Ãû³Æ
script, // Òì³£½Å±¾url
line, // Òì³£ÐкÅ
column, // Òì³£ÁкÅ
stack // Òì³£¶ÑÕ»ÐÅÏ¢
} = err;
// vmΪÅ׳öÒì³£µÄ Vue ʵÀý
// infoΪ Vue ÌØ¶¨µÄ´íÎóÐÅÏ¢£¬±ÈÈç´íÎóËùÔÚµÄÉúÃüÖÜÆÚ¹³×Ó
} |
Ŀǰscript¡¢line¡¢columnÕâ3¸öÐÅÏ¢´òÓ¡³öÀ´ÊÇundefined£¬²»¹ýÕâЩÐÅÏ¢ÔÚstackÖж¼¿ÉÒÔÕÒµ½£¬¿ÉÒÔͨ¹ýÕýÔòÆ¥ÅäÈ¥½øÐлñÈ¡£¬È»ºó½øÐÐÉϱ¨¡£
ͬÑùµÄÔÚreactÒ²ÌṩÁËÒì³£´¦ÀíµÄ·½Ê½£¬ÔÚ React 16.x °æ±¾ÖÐÒýÈëÁË Error Boundary£º
class
ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
// ½«Òì³£ÐÅÏ¢Éϱ¨¸ø·þÎñÆ÷
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
return '³ö´íÁË';
}
return this.props.children;
}
} |
È»ºóÎÒÃǾͿÉÒÔÕâÑùʹÓøÃ×é¼þ£º
<ErrorBoundary>
<MyWidget />
</ErrorBoundary> |
Òì³£Éϱ¨
ÒÔÉϽéÉÜÁËǰ¶ËÒì³£²¶»ñµÄÏà¹ØÖªÊ¶µã£¬ÄÇô½ÓÏÂÀ´ÎÒÃǼÈÈ»³É¹¦²¶»ñÁËÒì³££¬ÄÇô¸ÃÈçºÎÉϱ¨ÄØ£¿
Ôڽű¾´úÂëûÓб»Ñ¹ËõµÄÇé¿öÏ¿ÉÒÔÖ±½Ó²¶»ñºóÉÏ´«¶ÔÓ¦µÄÒì³£ÐÅÏ¢£¬ÕâÀï¾Í²»×ö½éÉÜÁË£¬ÏÂÃæÖ÷Òª½²½â³£¼ûµÄ´¦ÀíѹËõÎļþÉϱ¨µÄ·½·¨¡£
1. Ìá½»Òì³£
µ±²¶»ñµ½Ò쳣ʱ£¬ÎÒÃÇ¿ÉÒÔ½«Òì³£ÐÅÏ¢´«µÝ¸ø½Ó¿Ú£¬ÒÔwindow.onerrorΪÀý£º
window.onerror
= function(errorMessage, scriptURI, lineNo,
columnNo, error) {
// ¹¹½¨´íÎó¶ÔÏó
var errorObj = {
errorMessage: errorMessage || null,
scriptURI: scriptURI || null,
lineNo: lineNo || null,
columnNo: columnNo || null,
stack: error && error.stack ? error.stack
: null
};
if (XMLHttpRequest) {
var xhr = new XMLHttpRequest();
xhr.open('post', '/middleware/errorMsg', true);
// Éϱ¨¸ønodeÖмä²ã´¦Àí
xhr.setRequestHeader('Content-Type', 'application/json');
// ÉèÖÃÇëÇóÍ·
xhr.send(JSON.stringify(errorObj)); // ·¢ËͲÎÊý
}
} |
2. sourceMap½âÎö
Æäʵsource-map¸ñʽµÄÎļþÊÇÒ»ÖÖÊý¾ÝÀàÐÍ£¬¼ÈÈ»ÊÇÊý¾ÝÀàÐÍÄÇô¿Ï¶¨ÓнâÎöËüµÄ°ì·¨£¬Ä¿Ç°ÊÐÃæÉÏÒ²ÓÐרÃŽâÎöËüµÄÏàÓ¦¹¤¾ß°ü£¬ÔÚä¯ÀÀÆ÷»·¾³»òÕßnode»·¾³Ï±ȽÏÁ÷ÐеÄÊÇÒ»¿î½Ð×ö'source-map'µÄ²å¼þ¡£
ͨ¹ýrequire¸Ã²å¼þ£¬Ç°¶Ëä¯ÀÀÆ÷¿ÉÒÔ¶ÔmapÎļþ½øÐнâÎö£¬µ«ÒòΪǰ¶Ë½âÎöËٶȽÏÂý£¬ËùÒÔÕâÀï²»×öÍÆ¼ö£¬ÎÒÃÇ»¹ÊÇʹÓ÷þÎñÆ÷½âÎö¡£Èç¹ûÄãµÄÓ¦ÓÃÓÐnodeÖмä²ã£¬ÄÇôÄãÍêÈ«¿ÉÒÔ½«Òì³£ÐÅÏ¢Ìá½»µ½Öмä²ã£¬È»ºó½âÎömapÎļþºó½«Êý¾Ý´«µÝ¸øºǫ́·þÎñÆ÷£¬Öмä²ã´úÂëÈçÏ£º
const
express = require('express');
const fs = require('fs');
const router = express.Router();
const fetch = require('node-fetch');
const sourceMap = require('source-map');
const path = require('path');
const resolve = file => path.resolve(__dirname,
file);
// ¶¨Òåpost½Ó¿Ú
router.post('/errorMsg/', function(req, res)
{
let error = req.body; // »ñȡǰ¶Ë´«¹ýÀ´µÄ±¨´í¶ÔÏó
let url = error.scriptURI; // ѹËõÎļþ·¾¶
if (url) {
let fileUrl = url.slice(url.indexOf('client/'))
+ '.map'; // mapÎļþ·¾¶
// ½âÎösourceMap
let smc = new sourceMap.SourceMapConsumer(fs.readFileSync(resolve('../'
+ fileUrl), 'utf8')); // ·µ»ØÒ»¸öpromise¶ÔÏó
smc.then(function(result) {
// ½âÎöÔʼ±¨´íÊý¾Ý
let ret = result.originalPositionFor({
line: error.lineNo, // ѹËõºóµÄÐкÅ
column: error.columnNo // ѹËõºóµÄÁкÅ
});
let url = ''; // Éϱ¨µØÖ·
// ½«Òì³£Éϱ¨ÖÁºǫ́
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
errorMessage: error.errorMessage, // ±¨´íÐÅÏ¢
source: ret.source, // ±¨´íÎļþ·¾¶
line: ret.line, // ±¨´íÎļþÐкÅ
column: ret.column, // ±¨´íÎļþÁкÅ
stack: error.stack // ±¨´í¶ÑÕ»
})
}).then(function(response) {
return response.json();
}).then(function(json) {
res.json(json);
});
})
}
});
module.exports = router; |
ÕâÀïÎÒÃÇͨ¹ýǰ¶Ë´«¹ýÀ´µÄÒì³£Îļþ·¾¶»ñÈ¡·þÎñÆ÷¶ËmapÎļþµØÖ·£¬È»ºó½«Ñ¹ËõºóµÄÐÐÁкŴ«µÝ¸øsourceMap·µ»ØµÄpromise¶ÔÏó½øÐнâÎö£¬Í¨¹ýoriginalPositionFor·½·¨ÎÒÃÇÄÜ»ñÈ¡µ½ÔʼµÄ±¨´íÐÐÁкźÍÎļþµØÖ·£¬×îºóͨ¹ýajax½«ÐèÒªµÄÒì³£ÐÅϢͳһ´«µÝ¸øºǫ́´æ´¢£¬Íê³ÉÒì³£Éϱ¨¡£ÏÂͼ¿ÉÒÔ¿´µ½¿ØÖÆÌ¨´òÓ¡³öÁ˾¹ý½âÎöºóµÄÕæÊDZ¨´íλÖúÍÎļþ£º

¸½£ºsource-map API
3. ×¢Òâµã
ÒÔÉÏÊÇÒì³£²¶»ñºÍÉϱ¨µÄÖ÷Ҫ֪ʶµãºÍÁ÷³Ì£¬»¹ÓÐһЩÐèҪעÒâµÄµØ·½£¬±ÈÈçÄãµÄÓ¦Ó÷ÃÎÊÁ¿ºÜ´ó£¬ÄÇôһ¸öСÒì³£¶¼¿ÉÄÜ»á°ÑÄãµÄ·þÎñÆ÷¸ã¹Ò£¬ËùÒÔÉϱ¨µÄʱºò¿ÉÒÔ½øÐÐÐÅÏ¢¹ýÂ˺ͲÉÑùµÈ£¬ÉèÖÃÒ»¸öµ÷¿Ø¿ª¹Ø£¬·þÎñÆ÷Ò²¿ÉÒÔ¶ÔÏàËÆµÄÒì³£½øÐйýÂË£¬ÔÚÒ»¸öʱ¼ä¶ÎÄÚ²»½øÐжà´Î´æ´¢¡£ÁíÍâwindow.onerrorÕâÑùµÄÒì³£²¶»ñ²»Äܲ¶»ñpromiseµÄÒì³£´íÎóÐÅÏ¢£¬ÕâµãÐèҪעÒâ¡£
×îÖÕ´óÖµÄÁ÷³ÌͼÈçÏ£º

½áÓï
ǰ¶ËÒì³£²¶»ñÓëÉϱ¨ÊÇǰ¶ËÒì³£¼à¿ØµÄǰÌᣬÁ˽Ⲣ×öºÃÁËÒì³£Êý¾ÝµÄÊÕ¼¯ºÍ·ÖÎö²ÅÄÜʵÏÖÒ»¸öÍêÉÆµÄ´íÎóÏìÓ¦ºÍ´¦Àí»úÖÆ£¬×îÖÕ´ï³ÉÊý¾Ý¿ÉÊÓ»¯¡£ |