How to handle non-fatal errors during a batch operation? Most tutorials about Drupal batch processing suggests that you provide something like the following as a callback for when the batch has finished.

function mymodule_finished($success, $results, $operations) {
  if ($success) {
    drupal_set_message(t('Success'));
  } else {
    $error_operation = reset($operations);
    drupal_set_message(t('At least one error occurred'));
  }
}


This is also how my finished-callback looks like (I know you can report more fancy statistics about the operations, but that is not relevant here. I want to keep this question simple).

I want to loop through a bunch of files in a batch and report at the end if any of them are not readable by the web server.  I do not want to abort the batch when a non readable file is found.

My test site is a clean Drupal 7.37 + Devel and a custom module called "mymodule".

This is how operations function for processing a single file looks like:

function mymodule_process_one($file, &amp;$context) {
  $context['results'][] = check_plain($file);
  if (!is_readable ($file)) {
    // I need some code here that indicates that this is an error.
  }
}


I've indicated with a comment were I think there should be some code that indicates that there is some non-fatal error.  My question is: What should this code be?

I've made sure that one of files processed are not readable.  Using Devel to print out the three variables passed into mymodule_finished, this is what I get:

$success is TRUE.
$results is an array with all the file names.
$operations is an empty array.

Since there is no actual code in the operations-function to mark an unreadable file as an error , my finished-callback always print "Success", even if there are one or more unreadable files in the batch.  How can I make it report any errors at the end?

PS: I've searched the site and found examples on how to terminate the batch process if a fatal error occurs in an operation - e.g.: How to terminate a batch when an error occurs and
Can a batch process be stopped.  I am not interested in that.  I want an answer that explains how to process all items and produce an error message in finished callback if one or more operations failed.

Edit: I know that I can accomplish this by using a global db variable as an error flag. However, I am not interested in workarounds.  I want to learn how do this correctly using the batch API.
Preamble:
The answer given by burnsjermey did help me find the solution. He deserves kudos for pointing me to the correct documentation and this project on github. Both helped a lot, so I've accepted his answer.

However, his answer contains a lot of stuff that has nothing to do with the question. Also, his code examples have bugs that stops them from working. Therefore, I also want to add a self-answer containing only code snippets that are relevant to the question asked.

Self-answer:
First, as pointed out in the API documentation, non-fatal error management should be handled using 'results'. Hence, when we encounter a non-fatal error, we add an error message to the results array:

function mymodule_process_one($file, &amp;$context) {
  if (!is_readable ($file)) {
    $context['results']['error'][] = t('@file is not readable.', array('@file' =&gt; $file));
  }
  else {
    $context['results'][] = t('@file processed.', array('@file' =&gt; $file));
  }
}


Then, in the finished-callback, we put code that looks for these errors, and prints them out if there are any.

function mymodule_finished($success, $results, $operations) {
  if ($success) {
    if (isset($results['error'])) {
      drupal_set_message(t('There were !count non-fatal error(s):', array(
       '!count' =&gt; count($results['error']),
      )), 'error');
      foreach ($results['error'] as $error) {
         drupal_set_message($error, 'error');
      }
    }
    else {
      drupal_set_message(t('No errors.'));
    }
  } else {
    $error_operation = reset($operations);
    drupal_set_message(t('A fatal error occurred'));
  }
}


That's all folks!

PS:
If you want to learn how to handle fatal errors during batch processing, the best answer is the accepted answer to: Can a batch process be stopped.