Repository: borgbackup/borg

Issue:
traceback when trying to delete non-existent archive
From the borgbackup mailing list:

I am testing out borg, and accidentally did:

```
borg create borgrepo::test4 ~
```

after 3 previous test archives were created using an --exclude-if-present .nobackup option.

When I noticed the missing --exclude-if-present in the above create (because it was taking too
long), I ^C'ed it, then tried:

```
borg delete borgrepo::test4
```

and got this failure (<...> obfuscations added):

```
Local Exception
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/borg/archiver.py", line 4501, in main
    exit_code = archiver.run(args)
  File "/usr/lib/python3.7/site-packages/borg/archiver.py", line 4433, in run
    return set_ec(func(args))
  File "/usr/lib/python3.7/site-packages/borg/archiver.py", line 166, in wrapper
    return method(self, args, repository=repository, **kwargs)
  File "/usr/lib/python3.7/site-packages/borg/archiver.py", line 1257, in do_delete
    return self._delete_archives(args, repository)
  File "/usr/lib/python3.7/site-packages/borg/archiver.py", line 1304, in _delete_archives
    logger.info(msg.format(format_archive(manifest.archives[archive_name]), i, len(archive_names)))
  File "/usr/lib/python3.7/site-packages/borg/helpers.py", line 244, in __getitem__
    raise KeyError
KeyError

Platform: Linux <...> 5.3.6-1-MANJARO #1 SMP PREEMPT Sat Oct 12 09:30:05
UTC 2019 x86_64 Linux: arch Manjaro Linux
Borg: 1.1.10  Python: CPython 3.7.4 msgpack: 0.5.6
PID: 10547  CWD: <...>
sys.argv: ['/usr/bin/borg', 'delete', 'borgrepo::test4']
SSH_ORIGINAL_COMMAND: None
```

Is this borgrepo now fried?  If not, how can I recover it?



Discussion:
No, the repo is not fried, everything is fine.

But that is a rather unpretty way to say "archive test4 not found".
i just stumbled across this issue and wondered if the text shouldn't be the same as when the `list` command was issued on a non-existinng archive ?
Which is ''Archive XYZ does not exist' rather than "Archive XYZ not found".
 
Yeah, using the same message is of course preferable for consistency reasons.
The fix for this seems like 3 lines of code in archiver.py (around line 1270).  If you are looking for a fix for this, what's the process?  Push my branch and make a pull request?
There's already a PR for this, see #4818.

Resolving patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -1298,12 +1298,19 @@ def _delete_archives(self, args, repository):
 
         stats = Statistics()
         with Cache(repository, key, manifest, progress=args.progress, lock_wait=self.lock_wait) as cache:
+            msg_delete = 'Would delete archive: {} ({}/{})' if dry_run else 'Deleting archive: {} ({}/{})'
+            msg_not_found = 'Archive {} not found ({}/{}).'
             for i, archive_name in enumerate(archive_names, 1):
-                msg = 'Would delete archive: {} ({}/{})' if dry_run else 'Deleting archive: {} ({}/{})'
-                logger.info(msg.format(format_archive(manifest.archives[archive_name]), i, len(archive_names)))
-                if not dry_run:
-                    Archive(repository, key, manifest, archive_name, cache=cache).delete(
-                        stats, progress=args.progress, forced=args.forced)
+                try:
+                    archive_info = manifest.archives[archive_name]
+                except KeyError:
+                    logger.warning(msg_not_found.format(archive_name, i, len(archive_names)))
+                else:
+                    logger.info(msg_delete.format(format_archive(archive_info), i, len(archive_names)))
+                    if not dry_run:
+                        archive = Archive(repository, key, manifest, archive_name, cache=cache,
+                                          consider_part_files=args.consider_part_files)
+                        archive.delete(stats, progress=args.progress, forced=args.forced)
             if not dry_run:
                 manifest.write()
                 repository.commit(save_space=args.save_space)


Test patch: