唐代斯 發表於 2019-11-21 14:27:00

详解JavaScript错误捕获和上报流程

<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://img2018.cnblogs.com/blog/1060770/201911/1060770-20191121142132127-1774479657.jpg" alt="" width="951" height="396"></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">怎么捕获错误并且处理,是一门语言必备的知识。在JavaScript中也是如此。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">那怎么捕获错误呢?初看好像很简单,try-catch就可以了嘛!但是有的时候我们发现情况却繁多复杂。</span></p>
<ul>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><strong>Q1</strong>: 同步可以try-catch,但一个异步回调,比如setTimeOut里的函数还可以try-catch吗?</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><strong>Q2</strong>: Promise的错误捕获怎么做?</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><strong>Q3</strong>: async/await怎么捕获错误?</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><strong>Q4</strong>: 我能够在全局环境下捕获错误并且处理吗?</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><strong>Q5</strong>: React16有什么新的错误捕获方式吗?</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><strong>Q6</strong>: 捕获之后怎么上报和处理?</span></p>
</li>
</ul>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">问题有点多,我们一个一个来。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<h2 id="4771-1574297407246"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Q1. 同步代码里的错误捕获方式</span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">在同步代码里,我们是最简单的,只要try-catch就完了</span>&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test1 () {
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('callback err'<span style="color: rgba(0, 0, 0, 1)">);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (error) {
    console.log (</span>'test1:catch err successfully'<span style="color: rgba(0, 0, 0, 1)">);
}
}
test1();</span></pre>
</div>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出结果如下,显然是正常的</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE78585ab9e35576419b292c10e5cb4e55/39326" alt="" width="422" height="148" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE78585ab9e35576419b292c10e5cb4e55/39326"></span></p>
<h2 id="8495-1574296915924"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Q2. 普通的异步回调里的错误捕获方式(Promise时代以前)</span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">上面的问题来了,我们还能通过直接的try-catch在异步回调外部捕获错误吗?我们试一试</span>&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 尝试在异步回调外部捕获错误的结果</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test2 () {
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
    setTimeout (</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
      </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('callback err'<span style="color: rgba(0, 0, 0, 1)">);
    });
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (error) {
    console.log (</span>'test2:catch err successfully'<span style="color: rgba(0, 0, 0, 1)">);
}
}
test2();</span><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></pre>
</div>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE9803ce00b68e21a311eedb423f5170ec/39338" alt="" width="448" height="162" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE9803ce00b68e21a311eedb423f5170ec/39338"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">注意这里的Uncaught Error的文本,它告诉我们错误没有被成功捕捉。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">为什么呢? 因为try-catch的是属于同步代码,它执行的时候,setTimeOut内部的的匿名函数还没有执行呢。而内部的那个匿名函数执行的时候,try-catch早就执行完了。( error的内心想法:哈哈,只要我跑的够慢,try-catch还是追不上我!)</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">但是我们简单想一想,诶我们把try-catch写到函数里面不就完事了嘛!</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE2a7cbbfed08e28cfc452db02ed7be8be/39344" alt="" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE2a7cbbfed08e28cfc452db02ed7be8be/39344">&nbsp;</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test2_1 () {
setTimeout (</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('callback err'<span style="color: rgba(0, 0, 0, 1)">);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (error) {
      console.log (</span>'test2_1:catch err successfully'<span style="color: rgba(0, 0, 0, 1)">);
    }
});
}
test2_1();</span></pre>
</div>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出结果如下,告诉我们这方法可行</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE1320a2b1f88b38f446be8a59bfeb7c9a/39350" alt="" width="444" height="144" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE1320a2b1f88b38f446be8a59bfeb7c9a/39350"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">总结下Promise时代以前,异步回调中捕获和处理错误的方法</span></p>
<ul>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">在异步回调内部编写try-catch去捕获和处理,不要在外部哦</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">很多异步操作会开放error事件,我们根据事件去操作就可以了</span></p>
</li>
</ul>
<h2 id="9872-1574298940712"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Q3. Promise里的错误捕获方式</span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">可通过Promise.catch方法捕获</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test3 () {
</span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise ((resolve, reject) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('promise error'<span style="color: rgba(0, 0, 0, 1)">);
}).</span><span style="color: rgba(0, 0, 255, 1)">catch</span> (err =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    console.log (</span>'promise error'<span style="color: rgba(0, 0, 0, 1)">);
});
}</span></pre>
</div>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出结果</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE2d08e3ac2b8766f9f8c71e45c6eaa06b/39370" alt="" width="472" height="179" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE2d08e3ac2b8766f9f8c71e45c6eaa06b/39370"></span></p>
<p id="2796-1574299024247"><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&gt;&gt; reject方法调用和throw Error都可以通过Promise.catch方法捕获</span></strong></p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test4 () {
</span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise ((resolve, reject) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    reject (</span>'promise reject error'<span style="color: rgba(0, 0, 0, 1)">);
}).</span><span style="color: rgba(0, 0, 255, 1)">catch</span> (err =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    console.log (err);
});
}</span><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></pre>
</div>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出结果</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE6e1b33f6c15ecb30e65eeced2163ba86/39380" alt="" width="431" height="169" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE6e1b33f6c15ecb30e65eeced2163ba86/39380"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p id="5394-1574299227286"><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&gt;&gt; then方法中的失败回调和Promise.catch的关系</span></strong></p>
<ul>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">如果前面的then方法没写失败回调,失败时后面的catch是会被调用的</span></p>
</li>
<li>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">如果前面的then方法写了失败回调,又没抛出,那么后面的catch就不会被调用了</span></p>
</li>
</ul>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> then方法没写失败回调</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test5 () {
</span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise ((resolve, reject) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('promise error'<span style="color: rgba(0, 0, 0, 1)">);
})
    .then (success </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {})
    .</span><span style="color: rgba(0, 0, 255, 1)">catch</span> (err =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log (</span>'the error has not been swallowed up'<span style="color: rgba(0, 0, 0, 1)">);
    });
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> then方法写了失败回调</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test5 () {
</span><span style="color: rgba(0, 0, 255, 1)">new</span> Promise ((resolve, reject) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('promise error'<span style="color: rgba(0, 0, 0, 1)">);
})
    .then (success </span>=&gt; {},err =&gt;<span style="color: rgba(0, 0, 0, 1)"> {})
    .</span><span style="color: rgba(0, 0, 255, 1)">catch</span> (err =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      console.log (</span>'the error has not been swallowed up'<span style="color: rgba(0, 0, 0, 1)">);
    });
}</span></pre>
</div>
</div>
<p><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出分别为</span></strong></p>
<div class="para-text">
<pre><span class="yne-token yne-number" style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">1.<span class="yne-plain">the error has not been swallowed up</span></span></pre>
<pre><span class="yne-token yne-number" style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">2.<span class="yne-plain">无输出</span></span></pre>
</div>
<h2 id="2245-1574299571863"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Q4.async/await里的错误捕获方式</span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">对于async/await这种类型的异步,我们可以通过try-catch去解决</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre>async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> test6 () {
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
    await getErrorP ();
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (error) {
    console.log (</span>'async/await error with throw error'<span style="color: rgba(0, 0, 0, 1)">);
}
}

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getErrorP () {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise ((resolve, reject) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('promise error'<span style="color: rgba(0, 0, 0, 1)">);
});
}
test6();</span></pre>
</div>
<pre></pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出结果如下</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE1e2d11f34994e5b85e60975109eb3f3e/39414" alt="" width="516" height="178" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE1e2d11f34994e5b85e60975109eb3f3e/39414"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p id="2754-1574303947271"><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&gt;&gt; 如果被await修饰的Promise因为reject调用而变化,它也是能被try-catch的</span></strong></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">(我已经证明了这一点,但是这里位置不够,我写不下了)</span></p>
<h2 id="7310-1574303869479"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Q5.在全局环境下如何监听错误</span></h2>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">window.onerror可以监听全局错误,但是很显然错误还是会抛出</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre>window.onerror = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
console.log (</span>'global error'<span style="color: rgba(0, 0, 0, 1)">);
};
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('global error');</pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">输出如下</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCEe6e93495ba82575b9e754d84ff13da3d/39432" alt="" width="493" height="212" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCEe6e93495ba82575b9e754d84ff13da3d/39432"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<h2 id="9737-1574304397295"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Q6.在React16以上如何监听错误</span></h2>
<p id="5037-1574304439936"><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&gt;&gt; componentDidCatch和getDerivedStateFromError钩子函数</span></strong></p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">class Bar extends React.Component {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听组件错误</span>
<span style="color: rgba(0, 0, 0, 1)">componentDidCatch(error, info) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({ error, info });
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 更新 state 使下一次渲染能够显示降级后的 UI</span>
<span style="color: rgba(0, 0, 0, 1)">static getDerivedStateFromError(error) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> { hasError: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> };
}
render() {
}
}</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: 14pt"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">有错误,那肯定要上报啊!不上报就发现不了Bug这个样子。Sentry这位老哥就是个人才,日志记录又好看,每次见面就像回家一样</span></strong></span></p>
<p><span style="font-size: 18pt; font-family: &quot;Microsoft YaHei&quot;"><strong>&nbsp;</strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<h2><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Sentry简单介绍</span></h2>
<blockquote>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Sentry provides open-source and hosted error monitoring that helps all software<br>teams discover, triage, and prioritize errors in real-time.<br>One million developers at over fifty thousand companies already ship<br>better software faster with Sentry. Won’t you join them?<br>—— Sentry官网</span></p>


</blockquote>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">Sentry是一个日志上报系统,Sentry 是一个实时的日志记录和汇总处理的平台。专注于错误监控,发现和数据处理,可以让我们不再依赖于用户反馈才能发现和解决线上bug。让我们简单看一下Sentry支持哪些语言和平台吧<img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE3333feb88211123c14c0f9282061fa80/39154" alt="" width="867" height="541" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE3333feb88211123c14c0f9282061fa80/39154"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">在JavaScript领域,Sentry的支持也可以说是面面俱到</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCEd7672dae4bc250d4405764eb5c979c4c/39159" alt="" width="770" height="287" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCEd7672dae4bc250d4405764eb5c979c4c/39159"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">参考链接
https:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">docs.sentry.io/platforms/</span><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">Sentry的功能简单说就是,你在代码中catch错误,然后调用Sentry的方法,然后Sentry就会自动帮你分析和整理错误日志,例如下面这张图截取自Sentry的网站中</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE378530ca50d2900f3695cc247043e49c/39219" alt="" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE378530ca50d2900f3695cc247043e49c/39219"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<h2 id="8624-1574232086142"><span style="font-size: 18px"><span style="font-family: &quot;Microsoft YaHei&quot;">在JavaScript中使用Sentry</span><span style="font-family: &quot;Microsoft YaHei&quot;">&nbsp;</span></span></h2>
<p><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">1.首先呢,你当然要注册Sentry的账号</span></strong></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">这个时候Sentry会自动给你分配一个唯一标示,这个标示在Sentry里叫做 dsn</span></p>
<p><span style="font-size: 16px"><strong>2. 安卓模块并使用基础功能</strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">安装@sentry/browser</span>&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre>npm install @sentry/browser</pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">在项目中初始化并使用</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre>import * as Sentry from '@sentry/browser'<span style="color: rgba(0, 0, 0, 1)">;

Sentry.init ({
dsn: </span>'xxxx'<span style="color: rgba(0, 0, 0, 1)">,
});

</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> Error ('我是一个error'<span style="color: rgba(0, 0, 0, 1)">);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 捕捉错误</span>
<span style="color: rgba(0, 0, 0, 1)">Sentry.captureException (err);
}</span></pre>
</div>
</div>
<p><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">3.上传sourceMap以方便在线上平台阅读出错的源码</span></strong></p>
<p id="4430-1574233583286" class="block-view code-view yne-code-theme-default" data-language="javascript" data-theme="default">&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 安装</span>
$ npm install --save-dev @sentry/webpack-plugin
$ yarn add --dev @sentry/webpack-plugin

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 配置webpack</span>
const SentryWebpackPlugin = require('@sentry/webpack-plugin'<span style="color: rgba(0, 0, 0, 1)">);
module.exports </span>=<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> other configuration</span>
<span style="color: rgba(0, 0, 0, 1)">plugins: [
    </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SentryWebpackPlugin({
      include: </span>'.'<span style="color: rgba(0, 0, 0, 1)">,
      ignoreFile: </span>'.sentrycliignore'<span style="color: rgba(0, 0, 0, 1)">,
      ignore: [</span>'node_modules', 'webpack.config.js'<span style="color: rgba(0, 0, 0, 1)">],
      configFile: </span>'sentry.properties'<span style="color: rgba(0, 0, 0, 1)">
    })
]
};</span><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></pre>
</div>
</div>
<p><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">4. 为什么不是raven.js?</span></strong></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE6bf5f06365f68e8dc45183a984806b92/39178" alt="" width="693" height="273" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE6bf5f06365f68e8dc45183a984806b92/39178"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">&nbsp;</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px"><img src="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE74c5667ed074a557b233f7b7315bb770/39180" alt="" width="678" height="180" data-media-type="image" data-original="https://note.youdao.com/yws/public/resource/25271a3b5e7d0944c5891c67d3fc65c0/xmlnote/WEBRESOURCE74c5667ed074a557b233f7b7315bb770/39180"></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 已经废弃,虽然你还是可以用</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> Raven = require('raven-js'<span style="color: rgba(0, 0, 0, 1)">);
Raven
.config(</span>'xxxxxxxxxxx_dsn'<span style="color: rgba(0, 0, 0, 1)">)
.install();</span></pre>
</div>
<p>&nbsp;</p>
<h2 id="7259-1574232567559"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px">Sentry的核心功能总结</span></h2>
<p><strong><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 16px">捕获错误</span></strong></p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="font-size: 12px"><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
aFunctionThatMightFail();
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
Sentry.captureException(err);
}</span></span></pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">设置该错误发生的用户信息</span></strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">下面每个选项都是可选的,但必须 存在一个选项 才能使Sentry SDK捕获用户: id</span>&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Sentry.setUser({
    id:</span>"penghuwan12314"<span style="color: rgba(0, 0, 0, 1)">
email: </span>"penghuwan@example.com"<span style="color: rgba(0, 0, 0, 1)">,
username:</span>"penghuwan"<span style="color: rgba(0, 0, 0, 1)">,
ip_addressZ:</span>'xxx.xxx.xxx.xxx'<span style="color: rgba(0, 0, 0, 1)">
});</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">设置额外数据</span></strong></span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre>Sentry.setExtra("character_name", "Mighty Fighter");</pre>
</div>
<pre><span style="font-size: 16px"><strong><span class="yne-plain" style="font-family: &quot;Microsoft YaHei&quot;">设置作用域</span></strong></span>&nbsp;</pre>
</div>
<div class="para-text">
<div class="cnblogs_code">
<pre>Sentry.withScope(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(scope) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 下面的set的效果只存在于函数的作用域内</span>
scope.setFingerprint(['Database Connection Error'<span style="color: rgba(0, 0, 0, 1)">]);
scope.setUser(someUser);
Sentry.captureException(err);
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在这里,上面的setUser的设置效果会消失</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">设置错误的分组</span></strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">整理日志信息,避免过度冗余</span>&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre>Sentry.configureScope(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(scope) {
scope.setFingerprint([</span>'my-view-function'<span style="color: rgba(0, 0, 0, 1)">]);
});</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">设置错误的级别</span></strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">在阅读日志时可以确定各个bug的紧急度,确定排查的优先书序</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre>Sentry.captureMessage('this is a debug message', 'debug'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">fatal,error,warning,info,debug五个值</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> fatal最严重,debug最轻</span></pre>
</div>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">自动记录某些事件</span></strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">例如下面的方法,会在每次屏幕调整时完成上报</span>&nbsp;</p>
<div class="para-text">
<div class="cnblogs_code">
<pre>window.addEventListener('resize', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(event){
Sentry.addBreadcrumb({
    category: </span>'ui'<span style="color: rgba(0, 0, 0, 1)">,
    message: </span>'New window size:' + window.innerWidth + 'x' +<span style="color: rgba(0, 0, 0, 1)"> window.innerHeight,
    level: </span>'info'<span style="color: rgba(0, 0, 0, 1)">
});
})</span></pre>
</div>
</div>
<p id="1333-1574233553768"><span style="font-size: 16px"><strong><span style="font-family: &quot;Microsoft YaHei&quot;">Sentry实践的运用</span></strong></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">根据环境设置不同的dsn</span></p>
<div class="para-text">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">let dsn;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (env === 'test'<span style="color: rgba(0, 0, 0, 1)">) {
    dsn </span>= '测试环境的dsn'<span style="color: rgba(0, 0, 0, 1)">;
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
    dsn </span>=
      '正式环境的dsn'<span style="color: rgba(0, 0, 0, 1)">;
}

Sentry.init ({
dsn
});</span></pre>
</div>
<p>&nbsp;</p>
<pre><span class="yne-token yne-keyword" style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp;</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14px">&nbsp;</span></p>

</div>
<div id="MySignature" role="contentinfo">
    我叫彭湖湾,请叫我胖湾<br><br>
来源:https://www.cnblogs.com/penghuwan/p/11905429.html
頁: [1]
查看完整版本: 详解JavaScript错误捕获和上报流程