Expose a failures list alongside the existing failedNotes counter so each
failure carries kind/path/sha/message. Also catches throws from
buildNoteDocs and bulkUpdate that previously aborted the whole loop.
A single null from queryFileContent silently exited cacheAllNotes,
leaving every later note uncached while the success toast still fired.
Skip the failing file, count failures, and surface them via errorMessage.