condition <- function(subclass, message, call = sys.call(-1), ...) {
  structure(
    class = c(subclass, "condition"),
    list(message = message, call = call, ...)
  )
}

malformed_log_entry_error <- function(text) {
  msg <- paste0("Malformed log entry: ", text)
  condition(
    c("malformed_log_entry_error", "error"),
    message = msg,
    text = text
  )
}

well_formed_log_entry <- function(text) {
  grepl("^(FATAL|WARN) ", text)
}

new_log_entry <- function(text) {
  message("Valid log entry: ", text)
  text
}

parse_log_entry <- function(text) {
  if (!well_formed_log_entry(text)) {
    stop(malformed_log_entry_error(text))
  }

  new_log_entry(text)
}

parse_log <- function(lines) {
  lapply(lines, function(text) {
    tryCatch(
      malformed_log_entry_error = function(e) NULL,
      parse_log_entry(text)
    )
  })
}

parse_log(c("FATAL killed"))
## Valid log entry: FATAL killed
## [[1]]
## [1] "FATAL killed"
parse_log(c(
  "WARN careful",
  "BAD wat"
))
## Valid log entry: WARN careful
## [[1]]
## [1] "WARN careful"
## 
## [[2]]
## NULL
parse_log <- function(lines) {
  lapply(lines, function(text) {
    withRestarts(
      parse_log_entry(text),
      skip_log_entry = function(e) NULL
    )
  })
}

try(parse_log(c(
  "WARN careful",
  "BAD wat"
)))
## Valid log entry: WARN careful
## Error in malformed_log_entry_error(text) : Malformed log entry: BAD wat
log_analyzer <- function() {
  logs <- find_all_logs()
  lapply(logs, analyze_log)
}

find_all_logs <- function() {
  list(
    c("FATAL killed"),
    c(
      "WARN careful",
      "BAD wat"
    )
  )
}

analyze_log <- function(log) {
  entries <- parse_log(log)
  invisible(lapply(entries, analyze_entry))
}

analyze_entry <- function(entry) {
  message("Analyzing log entry")
  dput(entry)
}

try(log_analyzer())
## Valid log entry: FATAL killed
## Analyzing log entry
## "FATAL killed"
## Valid log entry: WARN careful
## Error in malformed_log_entry_error(text) : Malformed log entry: BAD wat
log_analyzer <- function() {
  logs <- find_all_logs()

  withCallingHandlers(
    malformed_log_entry_error = function(e) invokeRestart("skip_log_entry"),
    lapply(logs, analyze_log)
  )
}

log_analyzer()
## Valid log entry: FATAL killed
## Analyzing log entry
## "FATAL killed"
## Valid log entry: WARN careful
## Analyzing log entry
## "WARN careful"
## Analyzing log entry
## NULL
## [[1]]
## [[1]][[1]]
## [1] "FATAL killed"
## 
## 
## [[2]]
## [[2]][[1]]
## [1] "WARN careful"
## 
## [[2]][[2]]
## NULL
skip_log_entry <- function(e) {
  r <- findRestart("skip_log_entry")
  if (is.null(r)) return()

  invokeRestart(r)
}

log_analyzer <- function() {
  logs <- find_all_logs()

  withCallingHandlers(
    malformed_log_entry_error = skip_log_entry,
    lapply(logs, analyze_log)
  )
}

log_analyzer()
## Valid log entry: FATAL killed
## Analyzing log entry
## "FATAL killed"
## Valid log entry: WARN careful
## Analyzing log entry
## "WARN careful"
## Analyzing log entry
## NULL
## [[1]]
## [[1]][[1]]
## [1] "FATAL killed"
## 
## 
## [[2]]
## [[2]][[1]]
## [1] "WARN careful"
## 
## [[2]][[2]]
## NULL