กลไกเหตุการณ์ทั่วโลกของ JavaScript


351

ฉันต้องการที่จะจับทุกข้อผิดพลาดฟังก์ชั่นที่ไม่ได้กำหนดโยน มีระบบจัดการข้อผิดพลาดทั่วโลกใน JavaScript หรือไม่ กรณีใช้งานคือการเรียกใช้ฟังก์ชันจากแฟลชที่ไม่ได้กำหนดไว้


คุณต้องการทำอย่างไรกับข้อผิดพลาดเมื่อคุณพบข้อผิดพลาด? คุณเพียงแค่ต้องเข้าสู่ระบบเพื่อให้คุณสามารถสร้างฟังก์ชั่นที่หายไปหรือคุณกำลังมองหาที่จะหยุดข้อยกเว้นจากการทำลายรหัสของคุณ?
Dan Herbert

2
ฉันต้องการรับชื่อฟังก์ชั่นที่หายไปที่ถูกเรียกและขึ้นอยู่กับการมีอยู่ของสตริงที่เรียกใช้ฟังก์ชันของตัวเอง การเรียกฟังก์ชันใด ๆ ที่มีสตริง 'ปิด' จะเรียกการปิดของฉัน () ฉันต้องการดักจับข้อผิดพลาด ณ จุดนั้น

2
ข้อยกเว้นให้ฟังก์ชั่นนี้และสามารถ taylored เพียงจับข้อผิดพลาดที่เกี่ยวข้องกับฟังก์ชั่นที่ไม่ได้กำหนดด้วยฟังก์ชั่น "ยาม" ของมัน
Steven Wexler

คำตอบ:


193

สิ่งนี้ช่วยคุณได้หรือไม่:

<script type="text/javascript">
window.onerror = function() {
    alert("Error caught");
};

xxx();
</script>

ฉันไม่แน่ใจว่าจะจัดการข้อผิดพลาดของ Flash ได้อย่างไร ...

อัปเดต: มันไม่ทำงานใน Opera แต่ตอนนี้ฉันกำลังแฮ็ค Dragonfly เพื่อดูว่ามันได้รับอะไร คำแนะนำเกี่ยวกับการแฮ็ค Dragonfly มาจากคำถามนี้:

หน้าต่างเลียนแบบ onerror ใน Opera โดยใช้ javascript


3
ด้วยการเพิ่ม msg, file_loc, line_no params สิ่งนี้ควรทำเพื่อฉัน ขอบคุณ!

1
ฉันเข้าใจถูกต้องหรือไม่ว่ารหัสนี้จะแทนที่ตัวจัดการข้อผิดพลาดที่มีอยู่
Mars Robertson

@MarsRobertson ไม่
atilkan

@atilkan window.onerror = function() { alert(42) };ตอนนี้รหัสในคำตอบ: window.onerror = function() { alert("Error caught"); };ไม่ overriden ฉันยังคงไม่แน่ใจ ..
Mars Robertson

@MarsRobertson ฉันเข้าใจ มันอาจจะเขียนทับ ใช่มันเพิ่งผ่านการทดสอบ ใช้ addEventListener จะดีกว่า
atilkan

647

วิธีจับข้อผิดพลาด Javascript ที่ไม่สามารถจัดการได้

กำหนดwindow.onerrorกิจกรรมให้กับตัวจัดการเหตุการณ์เช่น:

<script type="text/javascript">
window.onerror = function(msg, url, line, col, error) {
   // Note that col & error are new to the HTML 5 spec and may not be 
   // supported in every browser.  It worked for me in Chrome.
   var extra = !col ? '' : '\ncolumn: ' + col;
   extra += !error ? '' : '\nerror: ' + error;

   // You can view the information in an alert to see things working like this:
   alert("Error: " + msg + "\nurl: " + url + "\nline: " + line + extra);

   // TODO: Report this error via ajax so you can keep track
   //       of what pages have JS issues

   var suppressErrorAlert = true;
   // If you return true, then error alerts (like in older versions of 
   // Internet Explorer) will be suppressed.
   return suppressErrorAlert;
};
</script>

ตามที่แสดงความคิดเห็นในรหัสหากค่าส่งคืนwindow.onerrorเป็นtrueแล้วเบราว์เซอร์ควรไม่แสดงกล่องโต้ตอบการแจ้งเตือน

window.onerror Event Fire ทำเมื่อไหร่?

โดยสรุปเหตุการณ์จะเพิ่มขึ้นเมื่อทั้ง 1) มีข้อยกเว้นที่ไม่ได้ตรวจสอบหรือ 2) เกิดข้อผิดพลาดในการรวบรวมเวลา

ข้อยกเว้นที่ไม่ได้ตรวจสอบ

  • โยน "บางข้อความ"
  • call_something_undefined ();
  • cross_origin_iframe.contentWindow.document, ข้อยกเว้นด้านความปลอดภัย

ข้อผิดพลาดในการรวบรวม

  • <script>{</script>
  • <script>for(;)</script>
  • <script>"oops</script>
  • setTimeout("{", 10);มันจะพยายามรวบรวมอาร์กิวเมนต์แรกเป็นสคริปต์

เบราว์เซอร์ที่รองรับ window.onerror

  • Chrome 13+
  • Firefox 6.0+
  • Internet Explorer 5.5+
  • Opera 11.60+
  • Safari 5.1+

ภาพหน้าจอ:

ตัวอย่างของรหัส onerror ด้านบนที่ใช้งานได้หลังจากเพิ่มสิ่งนี้ลงในหน้าทดสอบ:

<script type="text/javascript">
call_something_undefined();
</script>

การแจ้งเตือน Javascript แสดงข้อมูลข้อผิดพลาดรายละเอียดโดยเหตุการณ์ window.onerror

ตัวอย่างการรายงานข้อผิดพลาด AJAX

var error_data = {
    url: document.location.href,
};

if(error != null) {
    error_data['name'] = error.name; // e.g. ReferenceError
    error_data['message'] = error.line;
    error_data['stack'] = error.stack;
} else {
    error_data['msg'] = msg;
    error_data['filename'] = filename;
    error_data['line'] = line;
    error_data['col'] = col;
}

var xhr = new XMLHttpRequest();

xhr.open('POST', '/ajax/log_javascript_error');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
    if (xhr.status === 200) {
        console.log('JS error logged');
    } else if (xhr.status !== 200) {
        console.error('Failed to log JS error.');
        console.error(xhr);
        console.error(xhr.status);
        console.error(xhr.responseText);
    }
};
xhr.send(JSON.stringify(error_data));

JSFiddle:

https://jsfiddle.net/nzfvm44d/

อ้างอิง:


3
มูลค่าการกล่าวถึง firefox ไม่ได้ให้กลับข้อผิดพลาดเมื่อthrowทำด้วยตนเอง stackoverflow.com/questions/15036165/…
Sebas

2
คำตอบที่ดี คุณสามารถใช้ "รายงานข้อผิดพลาดนี้ผ่าน ajax" ด้วยแพ็คเกจเช่น JSNLog ซึ่งทำบันทึก ajax และฝั่งเซิร์ฟเวอร์ให้คุณ
user1147862

4
นอกเหนือจากคำตอบนี้ฉันได้เพิ่มอ็อบเจกต์ err เพื่อให้สามารถติดตามสแต็กได้ stackoverflow.com/a/20972210/511438 ตอนนี้ฉันสามารถพัฒนาพร้อมข้อเสนอแนะเพิ่มเติมเนื่องจากข้อผิดพลาด dev ของฉันปรากฏเป็นกล่องที่ด้านบนของหน้า (ตามที่ฉันได้สร้างไว้)
Valamas

จะดีกว่าไหมที่จะแพ็คการใช้งาน onerror ของคุณในบล็อก try-catch (ละเว้น) ป้องกันไม่ให้ onerror ของคุณ () ส่งข้อผิดพลาดเพิ่มเติม (ไม่ใช่ว่าเป็นกรณีของที่นี่ แต่เพียงเพื่อให้แน่ใจว่า)
Pieter De Bie

1
@ super1ha1 คุณสามารถให้ jsfiddle ได้หรือไม่? ฉันไม่คิดว่าเบราว์เซอร์จะแนะนำการเปลี่ยนแปลงที่สำคัญซึ่งตัวจัดการเหตุการณ์ onerror หยุดยิงเหตุการณ์ คุณสามารถลอง jsfiddle นี้เพื่อดูตัวจัดการ onerror ทำงานได้: jsfiddle.net/nzfvm44d สิ่งนี้ยังใช้ได้กับฉันใน Chrome รุ่น 62.0.3202.94 (รุ่นทางการ) (64 บิต)
Sam

39

การจัดการข้อผิดพลาดที่ซับซ้อน

หากการจัดการข้อผิดพลาดของคุณซับซ้อนมากและอาจทำให้เกิดข้อผิดพลาดเองมันจะมีประโยชน์ในการเพิ่มการตั้งค่าสถานะเพื่อระบุว่าคุณอยู่ใน "errorHandling-Mode" แล้ว ชอบมาก

var appIsHandlingError = false;

window.onerror = function() {
    if (!appIsHandlingError) {
        appIsHandlingError = true;
        handleError();
    }
};

function handleError() {
    // graceful error handling
    // if successful: appIsHandlingError = false;
}

มิฉะนั้นคุณอาจพบว่าตัวเองอยู่ในวงวนไม่สิ้นสุด


29
หรือวิธีที่ล้มเหลวที่ปลอดภัยกว่าคือการใช้handleErrorวิธีจับลองวิธี
Aidiakapi

8
คุณไม่สามารถใช้ลองจับถ้าคุณมีการเรียกแบบซิงโครนัสในการจัดการข้อผิดพลาดของคุณ ดังนั้นทางออกของเขายังคงเป็นทางออกที่ดี
Emrys Myrooin

@EmrysMyrooin จะยังทำให้เกิดการซิงค์หรือการวนซ้ำของ async โดยการจัดการข้อผิดพลาดและอาจล้มเหลวโดยไม่มีข้อมูลสแต็กที่ใช้งานได้
inf3rno

1
ฉันคิดว่าควรตั้งค่าสถานะใหม่ในบางจุดใช่ไหม ฉันเชื่อว่าเราต้องลอง / จับถ้ามีขนาดใหญ่ถ้าและตรวจสอบให้แน่ใจว่าการตั้งค่าสถานะถูกต้องก่อนที่จะออกจากวิธีการ onerror มิฉะนั้นจะจัดการข้อผิดพลาดเดียวเท่านั้น
Seb

23

ลองใช้Atatusซึ่งให้การติดตามข้อผิดพลาดขั้นสูงและการตรวจสอบผู้ใช้จริงสำหรับแอปเว็บที่ทันสมัย

https://www.atatus.com/

ให้ฉันอธิบายวิธีรับกองซ้อนที่สมบูรณ์พอสมควรในเบราว์เซอร์ทั้งหมด

การจัดการข้อผิดพลาดใน JavaScript

โมเดิร์น Chrome และ Opera สนับสนุนอย่างเต็มที่ HTML 5 ร่างข้อมูลจำเพาะสำหรับ ErrorEvent window.onerrorและ ในเบราว์เซอร์ทั้งสองนี้คุณสามารถใช้window.onerrorหรือเชื่อมโยงกับเหตุการณ์ 'ข้อผิดพลาด' อย่างถูกต้อง:

// Only Chrome & Opera pass the error object.
window.onerror = function (message, file, line, col, error) {
    console.log(message, "from", error.stack);
    // You can send data to your server
    // sendError(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (e) {
    console.log(e.error.message, "from", e.error.stack);
    // You can send data to your server
    // sendError(data);
})

น่าเสียดายที่ Firefox, Safari และ IE ยังคงอยู่และเราก็ต้องให้การสนับสนุนเช่นกัน เนื่องจาก stacktrace ไม่พร้อมใช้งานwindow.onerrorเราต้องทำงานอีกเล็กน้อย

แต่กลับกลายเป็นว่าสิ่งเดียวที่เราสามารถทำได้เพื่อรับ stacktraces จากข้อผิดพลาดคือการห่อทั้งหมดของรหัสของเราในบล็อกแล้วดูที่try{ }catch(e){ } e.stackเราสามารถทำให้กระบวนการค่อนข้างง่ายขึ้นด้วยฟังก์ชั่นที่เรียกว่า wrap ที่รับฟังก์ชั่นและส่งคืนฟังก์ชั่นใหม่ที่มีการจัดการข้อผิดพลาดที่ดี

function wrap(func) {
    // Ensure we only wrap the function once.
    if (!func._wrapped) {
        func._wrapped = function () {
            try{
                func.apply(this, arguments);
            } catch(e) {
                console.log(e.message, "from", e.stack);
                // You can send data to your server
                // sendError(data);
                throw e;
            }
        }
    }
    return func._wrapped;
};

วิธีนี้ใช้ได้ผล ฟังก์ชั่นใด ๆ ที่คุณห่อด้วยตนเองจะมีการจัดการข้อผิดพลาดที่ดี แต่ปรากฎว่าเราสามารถทำได้โดยอัตโนมัติในกรณีส่วนใหญ่

ด้วยการเปลี่ยนคำจำกัดความสากลของaddEventListenerมันเพื่อให้การล้อมรอบการโทรกลับโดยอัตโนมัติทำให้เราสามารถใส่try{ }catch(e){ }รหัสส่วนใหญ่ได้โดยอัตโนมัติ วิธีนี้ช่วยให้รหัสที่มีอยู่ยังคงทำงานต่อไป แต่เพิ่มการติดตามข้อยกเว้นคุณภาพสูง

var addEventListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
    addEventListener.call(this, event, wrap(callback), bubble);
}

เราต้องตรวจสอบให้แน่ใจว่ามันremoveEventListenerใช้งานได้ ในขณะนี้จะไม่เกิดขึ้นเนื่องจากข้อโต้แย้งaddEventListenerเปลี่ยนไป เราต้องแก้ไขสิ่งนี้กับprototypeวัตถุอีกครั้ง:

var removeEventListener = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
    removeEventListener.call(this, event, callback._wrapped || callback, bubble);
}

ส่งข้อมูลข้อผิดพลาดไปยังแบ็กเอนด์ของคุณ

คุณสามารถส่งข้อมูลข้อผิดพลาดโดยใช้แท็กภาพดังต่อไปนี้

function sendError(data) {
    var img = newImage(),
        src = 'http://yourserver.com/jserror&data=' + encodeURIComponent(JSON.stringify(data));

    img.crossOrigin = 'anonymous';
    img.onload = function success() {
        console.log('success', data);
    };
    img.onerror = img.onabort = function failure() {
        console.error('failure', data);
    };
    img.src = src;
}

Disclaimer: ฉันเป็นนักพัฒนาเว็บที่https://www.atatus.com/


yourserver.com/jserrorคืออะไร ส่วนที่เหลือบริการเว็บบริการ WCF ? ง่าย ๆ เกี่ยวกับแบ็กเอนด์?
Kiquenet

หากคุณต้องการส่งข้อผิดพลาด js จากเบราว์เซอร์ผู้ใช้ไปยังเซิร์ฟเวอร์ของคุณ คุณต้องเขียนแบ็กเอนด์ของคุณ ( http://yourserver.com) เพื่อรับและจัดเก็บ หากคุณเลือกatatus.comคุณไม่จำเป็นต้องทำอะไรเลย เพียงรวมสคริปต์สองบรรทัดในหน้าของคุณ
Fizer Khan

18

ดูเหมือนว่าwindow.onerrorจะไม่ให้การเข้าถึงข้อผิดพลาดที่เป็นไปได้ทั้งหมด มันไม่สนใจโดยเฉพาะ:

  1. <img> ข้อผิดพลาดในการโหลด (การตอบสนอง> = 400)
  2. <script> ข้อผิดพลาดในการโหลด (การตอบสนอง> = 400)
  3. ข้อผิดพลาดทั่วโลกถ้าคุณมีห้องสมุดอื่น ๆ ในแอปของคุณจัดการ window.onerrorในวิธีที่ไม่รู้จัก (jquery, angular, ฯลฯ )
  4. อาจมีหลายกรณีที่ฉันยังไม่พบหลังจากสำรวจสิ่งนี้ในตอนนี้ (iframes, stack overflow และอื่น ๆ )

นี่คือจุดเริ่มต้นของสคริปต์ที่จับข้อผิดพลาดเหล่านี้มากมายเพื่อให้คุณสามารถเพิ่มการดีบักที่มีประสิทธิภาพมากขึ้นในแอปของคุณในระหว่างการพัฒนา

(function(){

/**
 * Capture error data for debugging in web console.
 */

var captures = [];

/**
 * Wait until `window.onload`, so any external scripts
 * you might load have a chance to set their own error handlers,
 * which we don't want to override.
 */

window.addEventListener('load', onload);

/**
 * Custom global function to standardize 
 * window.onerror so it works like you'd think.
 *
 * @see http://www.quirksmode.org/dom/events/error.html
 */

window.onanyerror = window.onanyerror || onanyerrorx;

/**
 * Hook up all error handlers after window loads.
 */

function onload() {
  handleGlobal();
  handleXMLHttp();
  handleImage();
  handleScript();
  handleEvents();
}

/**
 * Handle global window events.
 */

function handleGlobal() {
  var onerrorx = window.onerror;
  window.addEventListener('error', onerror);

  function onerror(msg, url, line, col, error) {
    window.onanyerror.apply(this, arguments);
    if (onerrorx) return onerrorx.apply(null, arguments);
  }
}

/**
 * Handle ajax request errors.
 */

function handleXMLHttp() {
  var sendx = XMLHttpRequest.prototype.send;
  window.XMLHttpRequest.prototype.send = function(){
    handleAsync(this);
    return sendx.apply(this, arguments);
  };
}

/**
 * Handle image errors.
 */

function handleImage() {
  var ImageOriginal = window.Image;
  window.Image = ImageOverride;

  /**
   * New `Image` constructor. Might cause some problems,
   * but not sure yet. This is at least a start, and works on chrome.
   */

  function ImageOverride() {
    var img = new ImageOriginal;
    onnext(function(){ handleAsync(img); });
    return img;
  }
}

/**
 * Handle script errors.
 */

function handleScript() {
  var HTMLScriptElementOriginal = window.HTMLScriptElement;
  window.HTMLScriptElement = HTMLScriptElementOverride;

  /**
   * New `HTMLScriptElement` constructor.
   *
   * Allows us to globally override onload.
   * Not ideal to override stuff, but it helps with debugging.
   */

  function HTMLScriptElementOverride() {
    var script = new HTMLScriptElement;
    onnext(function(){ handleAsync(script); });
    return script;
  }
}

/**
 * Handle errors in events.
 *
 * @see http://stackoverflow.com/questions/951791/javascript-global-error-handling/31750604#31750604
 */

function handleEvents() {
  var addEventListenerx = window.EventTarget.prototype.addEventListener;
  window.EventTarget.prototype.addEventListener = addEventListener;
  var removeEventListenerx = window.EventTarget.prototype.removeEventListener;
  window.EventTarget.prototype.removeEventListener = removeEventListener;

  function addEventListener(event, handler, bubble) {
    var handlerx = wrap(handler);
    return addEventListenerx.call(this, event, handlerx, bubble);
  }

  function removeEventListener(event, handler, bubble) {
    handler = handler._witherror || handler;
    removeEventListenerx.call(this, event, handler, bubble);
  }

  function wrap(fn) {
    fn._witherror = witherror;

    function witherror() {
      try {
        fn.apply(this, arguments);
      } catch(e) {
        window.onanyerror.apply(this, e);
        throw e;
      }
    }
    return fn;
  }
}

/**
 * Handle image/ajax request errors generically.
 */

function handleAsync(obj) {
  var onerrorx = obj.onerror;
  obj.onerror = onerror;
  var onabortx = obj.onabort;
  obj.onabort = onabort;
  var onloadx = obj.onload;
  obj.onload = onload;

  /**
   * Handle `onerror`.
   */

  function onerror(error) {
    window.onanyerror.call(this, error);
    if (onerrorx) return onerrorx.apply(this, arguments);
  };

  /**
   * Handle `onabort`.
   */

  function onabort(error) {
    window.onanyerror.call(this, error);
    if (onabortx) return onabortx.apply(this, arguments);
  };

  /**
   * Handle `onload`.
   *
   * For images, you can get a 403 response error,
   * but this isn't triggered as a global on error.
   * This sort of standardizes it.
   *
   * "there is no way to get the HTTP status from a 
   * request made by an img tag in JavaScript."
   * @see http://stackoverflow.com/questions/8108636/how-to-get-http-status-code-of-img-tags/8108646#8108646
   */

  function onload(request) {
    if (request.status && request.status >= 400) {
      window.onanyerror.call(this, request);
    }
    if (onloadx) return onloadx.apply(this, arguments);
  }
}

/**
 * Generic error handler.
 *
 * This shows the basic implementation, 
 * which you could override in your app.
 */

function onanyerrorx(entity) {
  var display = entity;

  // ajax request
  if (entity instanceof XMLHttpRequest) {
    // 400: http://example.com/image.png
    display = entity.status + ' ' + entity.responseURL;
  } else if (entity instanceof Event) {
    // global window events, or image events
    var target = entity.currentTarget;
    display = target;
  } else {
    // not sure if there are others
  }

  capture(entity);
  console.log('[onanyerror]', display, entity);
}

/**
 * Capture stuff for debugging purposes.
 *
 * Keep them in memory so you can reference them
 * in the chrome debugger as `onanyerror0` up to `onanyerror99`.
 */

function capture(entity) {
  captures.push(entity);
  if (captures.length > 100) captures.unshift();

  // keep the last ones around
  var i = captures.length;
  while (--i) {
    var x = captures[i];
    window['onanyerror' + i] = x;
  }
}

/**
 * Wait til next code execution cycle as fast as possible.
 */

function onnext(fn) {
  setTimeout(fn, 0);
}

})();

มันสามารถใช้แบบนี้:

window.onanyerror = function(entity){
  console.log('some error', entity);
};

สคริปต์แบบเต็มมีการใช้งานเริ่มต้นที่พยายามพิมพ์เอนทิตี / ข้อผิดพลาดที่ได้รับในเวอร์ชั่นกึ่งอ่านได้ สามารถใช้เป็นแรงบันดาลใจสำหรับตัวจัดการข้อผิดพลาดเฉพาะแอพได้ การใช้งานเริ่มต้นยังเก็บการอ้างอิงไปยังเอนทิตีข้อผิดพลาด 100 ล่าสุดดังนั้นคุณสามารถตรวจสอบพวกเขาในเว็บคอนโซลหลังจากที่พวกเขาเกิดขึ้นเช่น:

window.onanyerror0
window.onanyerror1
...
window.onanyerror99

หมายเหตุ: สิ่งนี้ทำงานโดยการแทนที่เมธอดบนหลายเบราว์เซอร์ / ตัวสร้างดั้งเดิม สิ่งนี้อาจมีผลข้างเคียงที่ไม่ได้ตั้งใจ อย่างไรก็ตามมันมีประโยชน์ที่จะใช้ในระหว่างการพัฒนาเพื่อหาข้อผิดพลาดที่เกิดขึ้นเพื่อส่งบันทึกไปยังบริการต่าง ๆ เช่น NewRelic หรือ Sentry ระหว่างการพัฒนาเพื่อให้เราสามารถวัดข้อผิดพลาดระหว่างการพัฒนาและการจัดเตรียมได้ ระดับลึก มันสามารถปิดได้ในการผลิต

หวังว่านี่จะช่วยได้


1
เห็นได้ชัดว่าภาพทำให้เกิดข้อผิดพลาด: stackoverflow.com/a/18152753/607033
inf3rno

6
// display error messages for a page, but never more than 3 errors
window.onerror = function(msg, url, line) {
if (onerror.num++ < onerror.max) {
alert("ERROR: " + msg + "\n" + url + ":" + line);
return true;
}
}
onerror.max = 3;
onerror.num = 0;

6

หนึ่งควรรักษาโทรกลับ onerror ที่เกี่ยวข้องก่อนหน้านี้เช่นกัน

<script type="text/javascript">

(function() {
    var errorCallback = window.onerror;
    window.onerror = function () {
        // handle error condition
        errorCallback && errorCallback.apply(this, arguments);
    };
})();

</script>

3

หากคุณต้องการวิธีการแบบครบวงจรในการจัดการทั้งข้อผิดพลาดที่ไม่ได้รับการจัดการและการปฏิเสธสัญญาที่ไม่สามารถจัดการได้คุณอาจดูที่ห้องสมุดที่ไม่ได้ทำการตรวจสอบ

แก้ไข

<script type="text/javascript" src=".../uncaught/lib/index.js"></script>

<script type="text/javascript">
    uncaught.start();
    uncaught.addListener(function (error) {
        console.log('Uncaught error or rejection: ', error.message);
    });
</script>

มันฟังหน้าต่าง unhandledrejectionนอกเหนือไปจาก window.onerror


2
แลนซ์พอลลาร์ดในคำตอบข้างต้นกล่าวถึงข้อผิดพลาดเล็ก ๆ น้อย ๆ ที่ onerror ปกติไม่ได้จัดการ ห้องสมุดของคุณจัดการกับพวกเขาหรือไม่? หากบางส่วนของพวกเขาโปรดระบุที่?
Michael Freidgeim

@ MiFreidgeimSO-stopbeingevil เพียงตรวจสอบซอร์สโค้ด - ไม่น่าเสียดายที่ไม่มี Aleksandr Oleynikov: จะยอดเยี่ยมถ้าคุณสามารถสนับสนุนสิ่งนี้ - ฉันจะเปลี่ยน downvote ของฉันเป็น upvote ;-)
brillout

2

ฉันอยากจะแนะนำให้Trackjsลองใช้

เป็นการบันทึกข้อผิดพลาดเป็นบริการ

ตั้งค่าได้ง่ายอย่างน่าอัศจรรย์ เพียงเพิ่มหนึ่งบรรทัด <script> ลงในแต่ละหน้าและนั่นคือมัน นอกจากนี้ยังหมายความว่ามันจะง่ายที่จะลบหากคุณตัดสินใจว่าคุณไม่ชอบ

มีบริการอื่น ๆ เช่นSentry (ซึ่งเป็นโอเพ่นซอร์สหากคุณสามารถโฮสต์เซิร์ฟเวอร์ของคุณเอง) แต่มันไม่ได้ทำสิ่งที่ Trackjs ทำ Trackjs บันทึกการโต้ตอบของผู้ใช้ระหว่างเบราว์เซอร์และเว็บเซิร์ฟเวอร์ของคุณเพื่อให้คุณสามารถติดตามขั้นตอนของผู้ใช้ที่นำไปสู่ข้อผิดพลาดซึ่งต่างจากการอ้างอิงไฟล์และหมายเลขบรรทัดเท่านั้น


2
TrackJS ดูเหมือนจะไม่มีเทียร์ฟรีอีกต่อไปแม้ว่าจะมีการทดลองใช้ฟรี
pkaeding

นี่เป็นเรื่องปกติสำหรับการติดตามและการแจ้งเตือนถึงข้อผิดพลาด แต่ไม่ได้แก้ไขส่วนการจัดการ นึกคิดฉันคิดว่าผู้ถามกำลังมองหาวิธีที่จะจัดการกับข้อผิดพลาดเหล่านี้เพื่อให้รหัสที่เหลือยังคงทำงาน
wgp

ถ้าคุณจับเหตุการณ์ข้อผิดพลาดและเพิ่มการเรียก xhr ไปยังตัวบันทึกด้วยการติดตามสแต็กและสถานะแอปพลิเคชัน trackjs นั้นดีกว่าอย่างไร
inf3rno

2
@ inf3rno มันเป็นมากกว่าการติดตามสแต็คซึ่งเพิ่งติดตามจุดเริ่มต้นของข้อผิดพลาด TrackJS จะติดตามเซสชันผู้ใช้ทั้งหมดเพื่อให้คุณเห็นสิ่งที่นำไปสู่ นี่เป็นภาพหน้าจอเป็นตัวอย่างtrackjs.com/assets/images/scurrency.png
kane

1

คุณฟังเหตุการณ์ onerror โดยกำหนดฟังก์ชั่นให้กับ window.onerror:

 window.onerror = function (msg, url, lineNo, columnNo, error) {
        var string = msg.toLowerCase();
        var substring = "script error";
        if (string.indexOf(substring) > -1){
            alert('Script Error: See Browser Console for Detail');
        } else {
            alert(msg, url, lineNo, columnNo, error);
        }   
      return false; 
  };
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.