--- /dev/null
+ERR_NO_SUCH_CATEGORY = 1
+ERR_MISSING_ARG = 2
+ERR_UNKNOWN_COMMAND = 3
+ERR_ILLEGAL_STATE = 127
+
+class TimeTrackError(Exception):
+ @property
+ def exit_code(self) -> int:
+ return NotImplemented
+
+
+class IllegalStateError(TimeTrackError):
+ def exit_code(self) -> int:
+ return ERR_ILLEGAL_STATE
+
+
+class MissingArgumentError(TimeTrackError):
+ def __init__(self, *args: object) -> None:
+ super().__init__(
+ f"Missing argument: {args[0]}",
+ *args[1:])
+
+ def exit_code(self) -> int:
+ return ERR_MISSING_ARG
+
+
+class NoSuchCategoryError(TimeTrackError):
+ def __init__(self, category: str) -> None:
+ super().__init__(f"No such category: {category}")
+
+ def exit_code(self) -> int:
+ return ERR_NO_SUCH_CATEGORY
+
+
+class UnknownCommandError(TimeTrackError):
+ def __init__(self, *args: object) -> None:
+ super().__init__(
+ f"Unknown subcommand: {args[0]}",
+ *args[1:])
+
+ def exit_code(self) -> int:
+ return ERR_UNKNOWN_COMMAND
+