Việc chỉ định tùy chọn R chung để xử lý các lỗi không nghiêm trọng đã phù hợp với tôi, cùng với quy trình làm việc tùy chỉnh để giữ lại thông tin về lỗi và kiểm tra thông tin này sau khi lỗi. Tôi hiện đang chạy phiên bản R 3.4.1. Dưới đây, tôi đã bao gồm mô tả về quy trình làm việc phù hợp với tôi, cũng như một số mã tôi đã sử dụng để đặt tùy chọn xử lý lỗi chung trong R.
Như tôi đã định cấu hình, việc xử lý lỗi cũng tạo ra một tệp RData chứa tất cả các đối tượng trong bộ nhớ đang hoạt động tại thời điểm xảy ra lỗi. Kết xuất này có thể được đọc lại thành R bằng cách sử dụng load()
và sau đó các môi trường khác nhau như chúng tồn tại tại thời điểm xảy ra lỗi có thể được kiểm tra tương tác bằng cách sử dụng debugger(errorDump)
.
Tôi sẽ lưu ý rằng tôi có thể lấy số dòng trong traceback()
đầu ra từ bất kỳ hàm tùy chỉnh nào trong ngăn xếp, nhưng chỉ khi tôi sử dụng keep.source=TRUE
tùy chọn khi gọi source()
bất kỳ hàm tùy chỉnh nào được sử dụng trong tập lệnh của tôi. Nếu không có tùy chọn này, việc đặt tùy chọn xử lý lỗi chung như bên dưới đã gửi toàn bộ kết quả đầu ra của tệp traceback()
đến một nhật ký lỗi có tên error.log
, nhưng số dòng không khả dụng.
Đây là các bước chung mà tôi đã thực hiện trong quy trình làm việc của mình và cách tôi có thể truy cập kết xuất bộ nhớ và nhật ký lỗi sau lỗi R không tương tác.
Tôi đặt phần sau ở đầu tập lệnh chính mà tôi đang gọi từ dòng lệnh. Điều này đặt tùy chọn xử lý lỗi chung cho phiên R. Kịch bản chính của tôi đã được gọi myMainScript.R
. Các dòng khác nhau trong mã có các chú thích sau khi chúng mô tả những gì chúng làm. Về cơ bản, với tùy chọn này, khi R gặp lỗi kích hoạt stop()
, nó sẽ tạo tệp kết xuất RData (* .rda) của bộ nhớ đang hoạt động trên tất cả các môi trường hoạt động trong thư mục ~/myUsername/directoryForDump
và cũng sẽ ghi nhật ký lỗi có tên error.log
với một số thông tin hữu ích cho cùng một thư mục. Bạn có thể sửa đổi đoạn mã này để thêm các xử lý khác khi gặp lỗi (ví dụ: thêm dấu thời gian vào tệp kết xuất và tên tệp nhật ký lỗi, v.v.).
options(error = quote({
setwd('~/myUsername/directoryForDump'); # Set working directory where you want the dump to go, since dump.frames() doesn't seem to accept absolute file paths.
dump.frames("errorDump", to.file=TRUE, include.GlobalEnv=TRUE); # First dump to file; this dump is not accessible by the R session.
sink(file="error.log"); # Specify sink file to redirect all output.
dump.frames(); # Dump again to be able to retrieve error message and write to error log; this dump is accessible by the R session since not dumped to file.
cat(attr(last.dump,"error.message")); # Print error message to file, along with simplified stack trace.
cat('\nTraceback:');
cat('\n');
traceback(2); # Print full traceback of function calls with all parameters. The 2 passed to traceback omits the outermost two function calls.
sink();
q()}))
Đảm bảo rằng từ tập lệnh chính và bất kỳ lệnh gọi hàm nào tiếp theo, bất cứ khi nào một hàm được lấy nguồn, tùy chọn keep.source=TRUE
sẽ được sử dụng. Đó là, để tạo nguồn một hàm, bạn sẽ sử dụng source('~/path/to/myFunction.R', keep.source=TRUE)
. Điều này là bắt buộc để traceback()
đầu ra chứa số dòng. Có vẻ như bạn cũng có thể đặt tùy chọn này trên toàn cầu bằng cách sử dụng options( keep.source=TRUE )
, nhưng tôi chưa thử nghiệm tùy chọn này để xem nó có hoạt động hay không. Nếu bạn không cần số dòng, bạn có thể bỏ qua tùy chọn này.
- Từ đầu cuối (bên ngoài R), sử dụng tập lệnh chính ở chế độ hàng loạt
Rscript myMainScript.R
. Điều này bắt đầu một phiên R không tương tác mới và chạy tập lệnh myMainScript.R
. Đoạn mã được đưa ra ở bước 1 đã được đặt ở đầu myMainScript.R
thiết lập tùy chọn xử lý lỗi cho phiên R không tương tác.
- Gặp lỗi ở đâu đó trong quá trình thực thi
myMainScript.R
. Điều này có thể nằm trong chính tập lệnh chính hoặc được lồng vào một số hàm sâu. Khi gặp lỗi, việc xử lý sẽ được thực hiện như đã chỉ định ở bước 1 và phiên R sẽ kết thúc.
- Một tệp kết xuất RData có tên
errorDump.rda
và và nhật ký lỗi có tên error.log
được tạo trong thư mục được chỉ định bởi '~/myUsername/directoryForDump'
cài đặt tùy chọn xử lý lỗi chung.
Khi rảnh rỗi, hãy kiểm tra error.log
để xem xét thông tin về lỗi, bao gồm cả thông báo lỗi và dấu vết ngăn xếp đầy đủ dẫn đến lỗi. Đây là một ví dụ về nhật ký được tạo do lỗi; lưu ý các số sau #
ký tự là số dòng của lỗi tại các điểm khác nhau trong ngăn xếp cuộc gọi:
Error in callNonExistFunc() : could not find function "callNonExistFunc"
Calls: test_multi_commodity_flow_cmd -> getExtendedConfigDF -> extendConfigDF
Traceback:
3: extendConfigDF(info_df, data_dir = user_dir, dlevel = dlevel) at test_multi_commodity_flow.R#304
2: getExtendedConfigDF(config_file_path, out_dir, dlevel) at test_multi_commodity_flow.R#352
1: test_multi_commodity_flow_cmd(config_file_path = config_file_path,
spot_file_path = spot_file_path, forward_file_path = forward_file_path,
data_dir = "../", user_dir = "Output", sim_type = "spot",
sim_scheme = "shape", sim_gran = "hourly", sim_adjust = "raw",
nsim = 5, start_date = "2017-07-01", end_date = "2017-12-31",
compute_averages = opt$compute_averages, compute_shapes = opt$compute_shapes,
overwrite = opt$overwrite, nmonths = opt$nmonths, forward_regime = opt$fregime,
ltfv_ratio = opt$ltfv_ratio, method = opt$method, dlevel = 0)
Khi rảnh rỗi, bạn có thể tải errorDump.rda
vào phiên R tương tác bằng cách sử dụng load('~/path/to/errorDump.rda')
. Sau khi được tải, hãy gọi debugger(errorDump)
để duyệt tất cả các đối tượng R trong bộ nhớ trong bất kỳ môi trường hoạt động nào. Xem phần trợ giúp R debugger()
để biết thêm thông tin.
Quy trình làm việc này cực kỳ hữu ích khi chạy R trong một số loại môi trường sản xuất nơi bạn có các phiên R không tương tác được khởi chạy tại dòng lệnh và bạn muốn lưu giữ thông tin về các lỗi không mong muốn. Khả năng kết xuất bộ nhớ vào một tệp mà bạn có thể sử dụng để kiểm tra bộ nhớ đang hoạt động tại thời điểm xảy ra lỗi, cùng với việc có số dòng của lỗi trong ngăn xếp cuộc gọi, tạo điều kiện gỡ lỗi nhanh chóng sau khám nghiệm về nguyên nhân gây ra lỗi.