diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 382e1e03..3923e54a 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -865,6 +865,12 @@ Delete sync-token that are older than the specified time. (seconds) Default: `2592000` +#### skip_broken_item + +Skip broken item instead of triggering an exception + +Default: False + ##### hook Command that is run after changes to storage. Take a look at the diff --git a/config b/config index 4a2e2f29..9cc77ecb 100644 --- a/config +++ b/config @@ -99,6 +99,9 @@ # Delete sync token that are older (seconds) #max_sync_token_age = 2592000 +# Skip broken item instead of triggering an exception +#skip_broken_item = False + # Command that is run after changes to storage # Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"") #hook = diff --git a/radicale/config.py b/radicale/config.py index 27352bdc..31765634 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -211,6 +211,10 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([ "value": "2592000", # 30 days "help": "delete sync token that are older", "type": positive_int}), + ("skip_broken_item", { + "value": False, + "help": "skip broken item instead of triggering exception", + "type": bool}), ("hook", { "value": "", "help": "command that is run after changes to storage", diff --git a/radicale/storage/multifilesystem/base.py b/radicale/storage/multifilesystem/base.py index bbb02198..db82e9ee 100644 --- a/radicale/storage/multifilesystem/base.py +++ b/radicale/storage/multifilesystem/base.py @@ -40,6 +40,7 @@ class CollectionBase(storage.BaseCollection): # Path should already be sanitized self._path = pathutils.strip_path(path) self._encoding = storage_.configuration.get("encoding", "stock") + self._skip_broken_item = storage_.configuration.get("storage", "skip_broken_item") if filesystem_path is None: filesystem_path = pathutils.path_to_filesystem(folder, self.path) self._filesystem_path = filesystem_path diff --git a/radicale/storage/multifilesystem/get.py b/radicale/storage/multifilesystem/get.py index 0a1fd73f..ab3bd90e 100644 --- a/radicale/storage/multifilesystem/get.py +++ b/radicale/storage/multifilesystem/get.py @@ -101,7 +101,11 @@ class CollectionPartGet(CollectionPartCache, CollectionPartLock, cache_content = self._store_item_cache( href, temp_item, cache_hash) except Exception as e: - raise RuntimeError("Failed to load item %r in %r: %s" % + if self._skip_broken_item: + logger.warning("Skip broken item %r in %r: %s", href, self.path, e) + return + else: + raise RuntimeError("Failed to load item %r in %r: %s" % (href, self.path, e)) from e # Clean cache entries once after the data in the file # system was edited externally.