2015-06-29 13 views
8

Tôi đã thực hiện một ứng dụng phản ứng không hoạt động trực tiếp và những người sử dụng nó lưu ý rằng rất hiếm khi xảy ra một số lỗi lạ. Tôi không biết tại sao hoặc điều gì xảy ra, và không thể tái tạo nó.bạn có thể nắm bắt tất cả các lỗi của ứng dụng React.js bằng khối try/catch không?

Vì vậy, tôi tự hỏi nếu có một cách để bọc toàn bộ ứng dụng, hoặc một phần của nó, trong một khối try/catch để tôi có thể gửi lỗi đến một bản ghi lỗi trên máy chủ?

Tất cả những gì tôi đã đọc cho đến nay là bạn có thể bọc toàn bộ hàm render trong try/catch, nhưng điều đó sẽ không bắt được bất kỳ lỗi nào do quyền tương tác người dùng?

Trả lời

17

đây là những gì tôi đã kết thúc bằng

componentWillMount: function() 
{ 
    this.startErrorLog(); 
} 
startErrorLog:function() 
{ 
    window.onerror = (message,file,line,column,errorObject) => 
    { 
     column = column || (window.event && window.event.errorCharacter); 
     var stack = errorObject ? errorObject.stack : null; 

     //trying to get stack from IE 
     if(!stack) 
     { 
      var stack = []; 
      var f = arguments.callee.caller; 
      while (f) 
      { 
       stack.push(f.name); 
       f = f.caller; 
      } 
      errorObject['stack'] = stack; 
     } 

     var data = { 
      message:message, 
      file:file, 
      line:line, 
      column:column, 
      errorStack:stack, 
     }; 

     //here I make a call to the server to log the error 

     //the error can still be triggered as usual, we just wanted to know what's happening on the client side 
     return false; 
    } 
} 
+1

Điều này cần được bỏ phiếu nhiều hơn. Chính xác những gì tôi đang tìm kiếm. – Echiban

+1

Hey, tôi đã thử mã này và điều này hoạt động trên firefox nhưng tôi chỉ nhận được "Script Error" trên chrome. Bất kỳ ý tưởng làm thế nào để giải quyết điều này? – JiN

+0

@JiN Tôi đã gặp phải sự cố tương tự. Dường như ([xem tại đây] (https://blog.sentry.io/2016/05/17/what-is-script-error.html)) rằng thông báo "Lỗi Script" chung xảy ra khi có sự cố CORS . Tuy nhiên, tôi nhận được nó, ngay cả khi kịch bản của tôi dường như được tải trên cùng một tên miền, vì vậy ... – fraxture

2

Tôi đã gặp vấn đề tương tự. Tôi tạo ra một ứng dụng văn phòng, nơi tôi không có một giao diện điều khiển gỡ lỗi cũng như các công cụ phát triển, vì vậy tôi không thể tìm ra nơi xảy ra lỗi.

Tôi đã tạo một thành phần (một lớp es6) đã thu tất cả tin nhắn console, lưu thư vào một mảng riêng biệt và được gọi là hàm "thực" console.

log(message) { 
    const msg = new Log(message); 
    this.pushMessage(msg); 
    this._target.log(message); 
} 

nơi Log là một wrapper đơn giản với một messagetypethis._target là một tài liệu tham khảo trên window.console. Vì vậy, tôi cũng làm như vậy với info, warnerror.

Ngoài ra, tôi đã tạo phương thức handleThrownErrors(message, url, lineNumber) để bắt ngoại lệ.

window.onerror = this.handleThrownErrors.bind(this); 

Ít nhất tôi đã tạo một thể hiện của lớp (tôi gọi là LogCollector) và nối nó vào cửa sổ.

window.logCollector = new LogCollector(); 

Bây giờ tôi đã tạo ra một thành phần phản ứng nhận cá thể logCollector (window.logCollector) làm tài sản. Trong khoảng thời gian đều đặn, thành phần phản ứng sẽ kiểm tra các tin nhắn đã thu thập và hiển thị chúng trên màn hình.

componentDidMount() { 
    this.setInterval(this._forceUpdate, 500); 
}, 

_forceUpdate() { 
    this.setState({update: !this.state.update}); 
} 

this.setInterval() là chức năng riêng mà chỉ cần gọi window.setInterval().

Và trong render() phương pháp:

return (
    <div class="console"> 
     {this.props.logCollector.getMessages().map(this.createConsoleMessage)} 
    </div> 
); 

LƯU Ý: Điều quan trọng là để bao gồm các LogCollector trước tất cả file khác.

LƯU Ý: Giải pháp trên là phiên bản rất đơn giản. Ví dụ: Bạn có thể cải thiện nó bằng cách thêm người nghe tùy chỉnh (tin nhắn), hoặc bắt gặp lỗi 404 Not found (đối với tập lệnh js-script và css).

+0

vâng Tôi đang cố gắng ra window.onerror vào lúc này quá. Hy vọng nó sẽ bắt tất cả các lỗi phản ứng – Flion

+0

nó sẽ hoạt động, miễn là bạn xác định nó ** trước khi ** làm một cái gì đó khác. ;-) – marcel

+0

yup làm cho nó hoạt động ngay bây giờ ... Tất cả những gì tôi cần là một window.onerror = function (...) trong phương thức componentWillMount của thành phần chính – Flion

15

Bạn có thể tận dụng BatchingStrategy API Phản ứng để dễ dàng quấn một try/catch xung quanh tất cả các Phản ứng mã của bạn.Lợi ích của việc này hơn window.onerror là bạn nhận được một dấu vết ngăn xếp tốt đẹp trong tất cả các trình duyệt. Ngay cả các trình duyệt hiện đại như Microsoft Edge và Safari cũng không cung cấp dấu vết ngăn xếp cho window.onerror.

Đây là những gì nó trông giống như với Phản ứng 15,4:

import ReactUpdates from "react-dom/lib/ReactUpdates"; 
import ReactDefaultBatchingStrategy from "react-dom/lib/ReactDefaultBatchingStrategy"; 

let isHandlingError = false; 
const ReactTryCatchBatchingStrategy = { 
    // this is part of the BatchingStrategy API. simply pass along 
    // what the default batching strategy would do. 
    get isBatchingUpdates() { return ReactDefaultBatchingStrategy.isBatchingUpdates; }, 

    batchedUpdates (...args) { 
    try { 
     ReactDefaultBatchingStrategy.batchedUpdates(...args); 
    } catch (e) { 
     if (isHandlingError) { 
     // our error handling code threw an error. just throw now 
     throw e; 
     } 

     isHandlingError = true; 
     try { 
     // dispatch redux action notifying the app that an error occurred. 
     // replace this with whatever error handling logic you like. 
     store.dispatch(appTriggeredError(e)); 
     } finally { 
     isHandlingError = false; 
     } 
    } 
    }, 
}; 

ReactUpdates.injection.injectBatchingStrategy(ReactTryCatchBatchingStrategy); 

Full writeup đây: https://engineering.classdojo.com/blog/2016/12/10/catching-react-errors/

+0

Một lưu ý quan trọng: "Và một lưu ý cần lưu ý: React> = 15 nuốt và sửa lỗi trong khi phát triển' NODE_ENV === "" vì vậy chiến lược tạo khối này sẽ không thực sự tạo sự khác biệt trong môi trường dev. " – Johnny

+0

Bạn đặt nó ở đâu? Blog của bạn chỉ có đoạn mã nhưng không chỉ ra cách thực sự sử dụng nó trong một ứng dụng lớn. Nó sẽ là tốt đẹp để đưa ra một ý tưởng về việc thực hiện. –

+1

Thao tác này sẽ không còn hoạt động khi Phản hồi 16. Việc nhập lib không còn bị lộ – Dve

Các vấn đề liên quan