JS Advanced Debugging Tips: Capturing and analyzing JavaScript error details

Source: Internet
Author: User
Tags exception handling regular expression

Front-end engineers know that JavaScript has basic exception handling capabilities. We can throw the new error () and the browser throws an exception when we invoke the API error. But it is estimated that most front-end engineers have not considered collecting these exception information.

Anyway, as long as the JavaScript error after the refresh is no longer, the user can solve the problem by refreshing, the browser will not crash, when it did not happen well. This assumption was established before the single Page App was popular. Now the single Page APP runs for a period of time after a very complex state, the user may have a number of input operations to come here, said the refresh is refreshing ah? Does the previous operation have to be completely repeated? So we still need to capture and analyze these anomaly messages, Then we can modify the code to avoid impacting the user experience.

How exceptions are caught

We wrote the throw New Error () to capture, of course, because we know exactly where throw is written. However, the exception that occurs when invoking the browser API is not necessarily so easily captured, and some APIs are written in the standard to throw exceptions, and some APIs only individual browsers throw exceptions because of differences or flaws. For the former we can also capture through Try-catch, for which we must listen for global exceptions and then capture them.

Try-catch

If some browser APIs are known to throw exceptions, then we need to put the call inside the Try-catch to avoid an error causing the entire program to enter an illegal state. For example, Window.localstorage is an API that throws an exception when the write data exceeds the capacity limit, as is the case in Safari's privacy browsing mode.

try {localstorage.setitem (' Date ', Date.now ());} catch (Error) {ReportError (error);} Another common Try-catch scenario is the callback. Because the code for the callback function is not controllable, the quality of the code will not invoke any other API that throws an exception, we don't know. In order not to be able to execute other code after invoking the callback because of a callback error, it is necessary to return the call to the Try-catch.

Listeners.foreach (function (listener) {try {Listener ();} catch (Error) {ReportError (error);}); Window.onerror

For Try-catch, an exception can only be captured by Window.onerror if it is not covered.

Window.onerror = function (errormessage, Scripturi, linenumber) {ReportError ({message:errormessage, Script:scripturi, Line:linenumber}); Be careful not to use Window.addeventlistener or window.attachevent in the form of listening to Window.onerror. Many browsers only implement Window.onerror, or only WINDOW.ONERROR implementations are standard. Taking into account the definition of the draft standard is also Window.onerror, we use window.onerror just fine.

property is missing

Suppose we have a reporterror function to collect the caught exception and then bulk send it to the server-side store for query analysis, what information do we want to collect? More useful information includes: Error type (name), error message, script file address ( script), line numbers (lines), column numbers (columns), stack traces (stacks). If an exception is captured through Try-catch, the information is on the Error object (supported by mainstream browsers), so ReportError can collect the information as well. But if captured through Window.onerror, we all know that this event function has only 3 parameters, so the unexpected information for these 3 parameters is lost.

Serialization message

If the Error object is created by ourselves, then the error.message is controlled by us. Basically what we put into the error.message, the Window.onerror's first argument (message) is what. (browsers can actually make minor changes, such as adding ' uncaught Error: ' prefix.) So we can serialize the attributes we're focusing on (for example, JSON). stringify) is then deposited into the error.message and then deserialized on Window.onerror read. Of course, this is limited to the Error object we created ourselves.

Fifth parameter

Browser vendors are also aware of the limitations of using window.onerror, so start adding new parameters to the Window.onerror. In view of the fact that only line numbers do not appear to be symmetrical, IE first add the column number and place the fourth parameter. However, we are more concerned about the ability to get the full stack, so Firefox said to put the stack on the fifth parameter bar. But Chrome said it would be better to put the entire Error object on the fifth argument, and what attributes you want to read, including custom attributes. As a result of the faster chrome action, the new Window.onerror signature was implemented in Chrome 30, which led to the standard drafts being written accordingly.

Window.onerror = function (errormessage, Scripturi, linenumber, ColumnNumber, error) {if (error) {ReportError (error);} else {ReportError ({message:errormessage, Script:scripturi, Line:linenumber, Column:columnnumber});} Attribute Normalization

The Error object properties that we discussed earlier, whose names are based on the Chrome naming method, differ in how different browsers name the properties of the error object, such as script file addresses that are called scripts in chrome but are called filename in Firefox. Therefore, we also need a special function to normalize the Error object, that is, to map different attribute names to the uniform attribute names. The specific procedure can refer to this article. Although the browser implementation is updated, it is not too difficult for a human to maintain such a mapping.

Similar to the format of stack traces (stacks). This property preserves the stack information of an exception when it occurs in plain text. Because the text format used by each browser is different, it also requires manual maintenance of a regular expression, which is used to extract each frame's function name (identifier), file (script), row number (line) from plain text and column numbers (columns).

Security restrictions

If you've also encountered the message ' script error. ', you'll understand what I'm talking about, which is actually the browser's restrictions on different source (origin) script files. The reason for this security restriction is this: Suppose a network of silver in the user login after the return of HTML and anonymous users see the HTML is not the same, a Third-party Web site will be able to put the net silver URI into the script.src attribute. HTML of course can not be used as JS parsing, so the browser will throw an exception, and this Third-party Web site will be able to resolve the abnormal location to determine whether the user has logged in. This browser for different source script files thrown by the exception to filter, filtering only the "script error." Such a unchanged message, all the other attributes disappear.

For a certain size of the site, the script file on the CDN, not homologous is very normal. Now, as a small web site, common frameworks such as jQuery and backbone can directly reference the version on the public CDN to speed up user downloads. So this security constraint does cause some trouble, and the exception information we collect from Chrome and Firefox is useless ' Script error. '

CORS

To circumvent this limitation, just make sure that the script file and the page itself are homologous. But is the script file on the server without CDN acceleration? One solution is that the script files continue to be on the CDN, using XMLHttpRequest to download the content back through CORS, and then create what we all know about this step1, Step2, Step3 If there is a dependency, it must be performed in this order, or there may be an error. Browsers can request step1 and step3 files in parallel, but the order of execution is guaranteed. If we get the contents of Step1 and step3 through xmlhttprequest ourselves, we need to ensure that the order is correct. In addition, don't forget to Step2, step1 in the form of non-blocking download Step2 can be executed, so we must also artificially intervene step2 let it wait for Step1 to complete and then execute.

If we already have a complete set of tools to generate different pages on our site, we need to implement both Scheduleremotescript and Scheduleinlinescript functions, and make sure that they are processed after the first reference to the external script file, if an error Error.line is 3005, that means the actual error.script should be ' http://cdn.com/step3.js ', and the actual error.line should be 5. We can complete this line number in the previous mentioned ReportError function to check the work.

Of course, because we have no way to guarantee that each script file is only 1000 lines, it is possible that some script files are significantly less than 1000 lines, so there is no need to allocate 1000 lines of the interval to each

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.