Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
̸̸ǰ¶ËÒì³£²¶»ñÓëÉϱ¨
 
  3560  次浏览      29
  2018-3-30
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚ²©¿Í ,±¾ÎÄ·ÖÏíÁËǰ¶ËÒì³£¼à¿ØÖÐÐèÒªÁ˽âµÄÒì³£²¶»ñÓëÉϱ¨»úÖÆµÄһЩҪµã£¬Í¬Ê±°üº¬ÁËʵսÐÔÖʵ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µÄÒì³£´íÎóÐÅÏ¢£¬ÕâµãÐèҪעÒâ¡£

×îÖÕ´óÖµÄÁ÷³ÌͼÈçÏ£º

½áÓï

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

   
3560 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì