Я пытаюсь проверить, являются ли объекты результатом ошибок. Случай использования в основном возникает через цикл foreach()
, который вызывает ошибку (хотя для тестирования кажется достаточно просто назначить переменную simpleError()
), и я озадачен тем, как определить, когда это произошло: как я могу проверить, что данный объект является, по сути, ошибкой? Как только я решил, что это ошибка, что еще я могу извлечь, помимо сообщения? Возможно, мне не хватает чего-то о средствах обработки ошибок R, поскольку, как представляется, необходимо написать функцию тестирования объектов ошибок de novo.
Вот два примера: один использует foreach
, аргумент .errorhandling
установлен на pass
. Я начал использовать это как значение по умолчанию для крупномасштабной или автоматической обработки, в случае аномалии во фрагменте данных. Такие аномалии редки, и не стоит сбивать весь цикл цикла (особенно если эта аномалия происходит в конце, что по-видимому является поведением по умолчанию моего murphysListSortingAlgorithm()
;-)). Вместо этого требуется посмертное обнаружение.
library(foreach)
library(doMC)
registerDoMC(2)
results = foreach(ix = 1:10, .errorhandling = "pass") %dopar%{
if(ix == 6){
stop("Perfect")
}
if(ix == 7){
stop("LuckyPrime")
} else {
return(ix)
}
}
Для простоты здесь очень простая ошибка (по определению):
a = simpleError("SNAFU")
Пока не существует команды типа is.error()
, а команды типа typeof()
и mode()
кажутся бессмысленными, лучшее, что я нашел, это использовать class()
или attributes()
, что укажите атрибуты, указывающие на ошибку. Как я могу использовать их таким образом, чтобы гарантировать, что у меня есть ошибка и полностью обработать эту ошибку? Например, a$message
возвращает SNAFU
, но a$call
- NULL
. Должен ли я ожидать, что вы сможете извлечь что-нибудь полезное, скажем, res[[6]]$call
?
Примечание 1: Если у одного нет многоуровневой функции для воспроизведения первого примера, я должен указать, что results[[6]]
не совпадает с simpleError("Perfect")
:
> b = simpleError("Perfect")
> identical(results[[6]], b)
[1] FALSE
> results[[6]]
<simpleError in eval(expr, envir, enclos): Perfect>
> b
<simpleError: Perfect>
Это демонстрирует, почему я не могу (очень наивно) проверить, является ли элемент списка ванилом simpleError
.
Примечание 2. Я знаю try
и tryCatch
и использую их в некоторых контекстах. Однако я не совсем уверен, как я могу использовать их для постпроцесса вывода, например, цикла foreach
. Например, объект results
в первом примере: мне не кажется, что имеет смысл обрабатывать его элементы с помощью обертки tryCatch
. Для RHS операции, т.е. Цикла foreach()
, я не уверен, что tryCatch
будет делать то, что я намерен. Я могу использовать его, чтобы поймать ошибку, но я полагаю, мне нужно получить сообщение и вставить обработку в этот момент. Я вижу две проблемы: каждый цикл нужно обернуть с помощью tryCatch()
, отрицающей часть аргумента .errorhandling
, и я не могу позже обработать объект results
. Если это единственный способ сделать эту обработку, то это решение, но это означает, что ошибки не могут быть идентифицированы и обработаны аналогично многим другим объектам R, таким как матрицы, векторы, кадры данных и т.д.
Обновление 1. Я добавил дополнительный триггер остановки в цикле foreach
, чтобы дать два разных сообщения для идентификации и анализа, если это полезно.
Обновление 2. Я выбираю ответ Ричи Коттона. Кажется, это наиболее полное объяснение того, что я должен искать, хотя для полной реализации требуется несколько других битов кода (и недавняя версия R). Самое главное, он указывает, что есть два типа ошибок, которые мы должны иметь в виду, что особенно важно для тщательного изучения. См. Также комментарии и ответы других, чтобы полностью разработать собственную тестовую функцию is.error()
; ответ, который я дал, может быть полезным началом при поиске ошибок в списке результатов, а код Ричи - хорошая отправная точка для тестовых функций.