2017-02-28 17 views
9

Tôi cần chuyển đổi cảnh báo thành lỗi để có thể xử lý nó ở phía trên (cảnh báo bị nuốt ở đâu đó ở giữa, mà tôi không kiểm soát được; . Để làm điều này, tôi đang làm như sau:`withCallingHandlers` bên trong` tryCatch` tạo lỗi không thể sửa lỗi

warning_to_error = function (expr) 
    withCallingHandlers(expr, warning = stop) 

này hoạt động tuyệt vời:

> warning_to_error(warning('foobar')) 
Error in withCallingHandlers(expr, warning = stop) : foobar 

Thật không may, điều này làm cho các lỗi hoàn toàn uncatchable:

> try(warning_to_error(warning('foobar'))) 
Error in withCallingHandlers(expr, warning = stop) : foobar 

In my real situation, có là một số lớp giữa số warning_to_errortry của chúng tôi (bao gồm cả logic mà muffl es cảnh báo). Làm thế nào tôi có thể làm cho lỗi được nâng lên bởi trình xử lý cuộc gọi của tôi có thể bắt được? Rất tiếc, tôi không thể sử dụng tính năng khởi động lại như được mô tả in another Stack Overflow questionstop không xác định khởi động lại và tôi lại không kiểm soát được mã đang bắt đầu.

Trả lời

7

này sẽ cho bạn biết những gì đang xảy ra với định nghĩa của bạn về warning_to_error:

> tryCatch(warning_to_error(warning('foobar')), condition = print) 
<simpleWarning in withCallingHandlers(expr, warning = stop): foobar>``` 

Là tài liệu cho stop nói, khi bạn gọi stop với một điều kiện, điều kiện được báo hiệu để tìm kiếm bộ xử lý, có nghĩa là warning trình xử lý trong trường hợp này. Nếu bạn muốn một trình xử lý lỗi được gọi, bạn cần báo hiệu một điều kiện lỗi. Đó là những gì xảy ra khi bạn đặt options(warn = 2) chẳng hạn. Vì vậy, bạn cần một cái gì đó giống như

warning_to_error1 <- function (expr) 
    withCallingHandlers(expr, 
         warning = function(w) 
          stop("(converted from warning) ", 
           conditionMessage(w))) 

Cung cấp cho bạn

> tryCatch(warning_to_error1(warning('foobar')), 
+   error = function(e) print("Got it")) 
[1] "Got it" 

Lý tưởng nhất là chúng ta nên cung cấp một lớp học tình trạng và xây dựng cho các cảnh báo chuyển đổi sang các lỗi và sử dụng nội bộ cho warn = 2

+0

Cảm ơn, điều này làm cho hoàn hảo giác quan. Tôi thực sự cố gắng làm điều đó (= in/trả lại điều kiện để kiểm tra nó) nhưng những nỗ lực của tôi thất bại vì nó đơn giản không xảy ra với tôi rằng lớp học sẽ là bất cứ thứ gì khác ngoài 'lỗi'. Duh. –

+0

Nó sẽ còn lớn hơn nếu tôi bằng cách nào đó có thể giả mạo thông tin ngăn xếp cuộc gọi. Rất tiếc, tôi không thể đạt được điều này ngay cả khi sử dụng 'eval', được thực hiện trong' parent.frame() 'của' warning_to_error': theo dõi stack luôn kết thúc bằng 'eval'. Tôi đoán điều này là không thể? –

+1

Tạo một đối tượng điều kiện lỗi và lưu trữ kết quả 'sys.calls' trong nó trước khi chuyển nó tới' stop'. –

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