Область перехвата ошибки{}

#r

#r

Вопрос:

это приведет к выводу «ошибка не найдена!» дважды,

 x<-"no error found!"
dontchangex <- function()
{
  tryCatch(
    {
      x<- "break this" 1  
    },error= function(e)
    {
      x<-"oh no :("
    })
  print(x)
}
dontchangex()
print(x)
  

Из-за области ошибки{}. Как мне получить доступ к родительской области изнутри ошибки?
Редактировать: я хочу перейти к области tryCatch, а не выходить в глобальную область. То есть, это должно напечатать «о, нет :(«ошибка не найдена!»

Ответ №1:

Использовать <<-

 x<-"no error found!"
tryCatch(
  {
    x<- "break this" 1  
  },error= function(e)
  {
    x <<- conditionMessage(e)
  })
print(x)
  

но мне интересно, каков вариант использования? Возможно, вы хотите сообщить пользователю, что что-то пошло не так, но используйте sentinel, чтобы продолжить обработку. Затем вы можете принудительно преобразовать ошибку во что-то менее серьезное, либо в предупреждение (), либо в сообщение (), и вернуть sentinel из tryCatch()

 f = function() {
    if (runif(1) > .8) stop("oops")
    TRUE
}

g = function() {
    ## on error, warn user but continue with sentinel 'FALSE'
    tryCatch(f(), error=function(err) {
        warning(conditionMessage(err))
        NA
    })
}
  

с

 > options(warn=1)
> replicate(10, g())
Warning in value[[3L]](cond) : oops
Warning in value[[3L]](cond) : oops
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE NA NA  TRUE  TRUE
  

Если вас беспокоит область действия, то

 x <- 1
fun = function() {
    x <- "OK"
    tryCatch(stop("oops"), error=function(e) x <<- conditionMessage(e))
    x
}
  

с

 > fun()
[1] "oops"
> x
[1] 1
  

показывает, что <<- присваивается первому совпадающему символу в (иерархии) окружающих средах, поэтому не обязательно в глобальной среде.

«Окружающая» среда относится к среде, в которой была определена функция, а не к «родительскому фрейму» или среде, из которой была вызвана функция. Более или менее сложным испытанием для понимания принципов является прохождение этого

 f = function() {
    x <- 0
    function() {
        tryCatch({
            stop("oops")
        }, error=function(e) {
            x <<- conditionMessage(e)
        })
        ls()
    }
}
  

и объясните следующее поведение

 > f0 <- f()
> environment(f0)[["x"]]
[1] 0
> f0 <- f()
> environment(f0)[["x"]]
[1] 0
> f0()
character(0)
> environment(f0)[["x"]]
[1] "oops"
> x
Error: object 'x' not found
  

Комментарии:

1. разве это не помещает x в глобальную область? Я просто хочу перейти к области tryCatch, а не полностью к глобальному. Я отредактирую, чтобы уточнить, что это то, что я хочу

2. @hedgedandlevered но вы хотите напечатать (x) вне tryCatch, так что …? <<- находит первый символ во включающей области, поэтому не обязательно в глобальной среде (например, если весь ваш код был в функции f()).

3. print(x), который находится «вне» tryCatch, фактически находится в той же области, что и тело (часть без ошибок) tryCatch <<- помещает его в глобальную область. Я просто отредактировал еще раз, чтобы показать это и уточнить дальше.

4. @hedgedandlevered добавлен к моему ответу для дальнейшего уточнения области <<- назначения, которая не обязательно является глобальной средой

5. @hedgedandlevered: <<- будет искать фреймы, пока не найдет то, что ищет. Это означает, что он может или не может перейти к глобальному в зависимости от того, как выглядит ваша проблема. Одна из причин, по которой этого лучше избегать.

Ответ №2:

 x<-"no error found!"
dontchangex <- function()
{
  errorFound <- TRUE
  tryCatch(
    {
      x<- "break this" 1  
      errorFound <- FALSE
    },error= function(e){}
  )
  if(errorFound) x<-"oh no :("
  print(x)
}
dontchangex()
print(x)
  

Для ErrorFound устанавливается значение false только тогда, когда оно не прерывается, но затем мы создали собственный блок ошибок в той же области, когда это происходит