Anki/pylib/anki/errors.py
RumovZ c521753057
Refactor error handling (#2136)
* Add crate snafu

* Replace all inline structs in AnkiError

* Derive Snafu on AnkiError

* Use snafu for card type errors

* Use snafu whatever error for InvalidInput

* Use snafu for NotFoundError and improve message

* Use snafu for FileIoError to attach context

Remove IoError.
Add some context-attaching helpers to replace code returning bare
io::Errors.

* Add more context-attaching io helpers

* Add message, context and backtrace to new snafus

* Utilize error context and backtrace on frontend

* Rename LocalizedError -> BackendError.
* Remove DocumentedError.
* Have all backend exceptions inherit BackendError.

* Rename localized(_description) -> message

* Remove accidentally committed experimental trait

* invalid_input_context -> ok_or_invalid

* ensure_valid_input! -> require!

* Always return `Err` from `invalid_input!`

Instead of a Result to unwrap, the macro accepts a source error now.

* new_tempfile_in_parent -> new_tempfile_in_parent_of

* ok_or_not_found -> or_not_found

* ok_or_invalid -> or_invalid

* Add crate convert_case

* Use unqualified lowercase type name

* Remove uses of snafu::ensure

* Allow public construction of InvalidInputErrors (dae)

Needed to port the AnkiDroid changes.

* Make into_protobuf() public (dae)

Also required for AnkiDroid. Not sure why it worked previously - possible
bug in older Rust version?
2022-10-21 18:02:12 +10:00

128 lines
2.3 KiB
Python

# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import anki.collection
class AnkiException(Exception):
"""
General Anki exception that all custom exceptions raised by Anki should
inherit from. Allows add-ons to easily identify Anki-native exceptions.
When inheriting from a Python built-in exception other than `Exception`,
please supply `AnkiException` as an additional inheritance:
```
class MyNewAnkiException(ValueError, AnkiException):
pass
```
"""
class BackendError(AnkiException):
"An error originating from Anki's backend."
def __init__(
self,
message: str,
help_page: anki.collection.HelpPage.V | None,
context: str | None,
backtrace: str | None,
) -> None:
super().__init__()
self._message = message
self.help_page = help_page
self.context = context
self.backtrace = backtrace
def __str__(self) -> str:
return self._message
class Interrupted(BackendError):
pass
class NetworkError(BackendError):
pass
class SyncErrorKind(Enum):
AUTH = 1
OTHER = 2
class SyncError(BackendError):
def __init__(
self,
message: str,
help_page: anki.collection.HelpPage.V | None,
context: str | None,
backtrace: str | None,
kind: SyncErrorKind,
):
self.kind = kind
super().__init__(message, help_page, context, backtrace)
class BackendIOError(BackendError):
pass
class CustomStudyError(BackendError):
pass
class DBError(BackendError):
pass
class CardTypeError(BackendError):
pass
class TemplateError(BackendError):
pass
class NotFoundError(BackendError):
pass
class DeletedError(BackendError):
pass
class ExistsError(BackendError):
pass
class UndoEmpty(BackendError):
pass
class FilteredDeckError(BackendError):
pass
class InvalidInput(BackendError):
pass
class SearchError(BackendError):
pass
class AbortSchemaModification(AnkiException):
pass
# legacy
DeckRenameError = FilteredDeckError
AnkiError = AbortSchemaModification