Coverage for src / ezxl / exceptions.py: 93.94%
31 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-29 15:53 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-29 15:53 +0000
1# ///////////////////////////////////////////////////////////////
2# exceptions - EzXl exception hierarchy
3# Project: EzXl
4# ///////////////////////////////////////////////////////////////
6"""
7EzXl exception hierarchy.
9All public exceptions raised by the EzXl library. Consumer libraries should
10catch ``EzXlError`` as the base type, or specific subclasses for fine-grained
11handling.
13No exception defined here carries raw COM error objects in its public
14interface — callers must not depend on pywin32 internals.
15"""
17from __future__ import annotations
19# ///////////////////////////////////////////////////////////////
20# CLASSES
21# ///////////////////////////////////////////////////////////////
24class EzXlError(Exception):
25 """Base exception for all EzXl errors.
27 All exceptions raised by the EzXl library inherit from this class.
28 Catching ``EzXlError`` is sufficient to handle any EzXl-originated
29 failure without importing subclasses.
31 Args:
32 message: Human-readable description of the error.
33 cause: Original exception that triggered this error, if any.
35 Example:
36 >>> try:
37 ... raise EzXlError("something went wrong")
38 ... except EzXlError as e:
39 ... print(e)
40 something went wrong
41 """
43 def __init__(self, message: str, cause: BaseException | None = None) -> None:
44 super().__init__(message)
45 self.cause = cause
46 if cause is not None:
47 self.__cause__ = cause
50# ///////////////////////////////////////////////////////////////
51# COM AVAILABILITY ERRORS
52# ///////////////////////////////////////////////////////////////
55class ExcelNotAvailableError(EzXlError):
56 """Raised when Excel is not open or the COM server is unreachable.
58 Typically thrown when ``win32com.client.Dispatch`` or
59 ``win32com.client.GetActiveObject`` fails because no Excel process is
60 running, or because the COM registration is broken.
62 Args:
63 message: Human-readable description of the error.
64 cause: Original exception that triggered this error, if any.
66 Example:
67 >>> raise ExcelNotAvailableError(
68 ... "No running Excel instance found", cause=original_err
69 ... )
70 """
72 def __init__(self, message: str, cause: BaseException | None = None) -> None:
73 super().__init__(message, cause)
76class ExcelSessionLostError(EzXlError):
77 """Raised when an established COM connection is lost mid-operation.
79 This can happen when the user closes Excel while an automation session
80 is active, or when Excel crashes. Unlike ``ExcelNotAvailableError``,
81 this implies a previously valid connection existed.
83 Args:
84 message: Human-readable description of the error.
85 cause: Original exception that triggered this error, if any.
86 """
88 def __init__(self, message: str, cause: BaseException | None = None) -> None:
89 super().__init__(message, cause)
92class ExcelThreadViolationError(EzXlError):
93 """Raised when a COM call is attempted from the wrong thread.
95 Excel COM operates under the Single-Threaded Apartment (STA) model.
96 All COM calls must originate from the thread that created the
97 ``ExcelApp`` instance. This exception is raised proactively before
98 the COM call reaches the dispatcher to give a clear diagnostic.
100 Args:
101 message: Human-readable description of the error.
102 cause: Original exception that triggered this error, if any.
103 """
105 def __init__(self, message: str, cause: BaseException | None = None) -> None:
106 super().__init__(message, cause)
109# ///////////////////////////////////////////////////////////////
110# NAVIGATION ERRORS
111# ///////////////////////////////////////////////////////////////
114class WorkbookNotFoundError(EzXlError):
115 """Raised when a workbook cannot be found by name in the Excel session.
117 Args:
118 message: Human-readable description of the error.
119 cause: Original exception that triggered this error, if any.
121 Example:
122 >>> raise WorkbookNotFoundError("No workbook named 'report.xlsx'")
123 """
125 def __init__(self, message: str, cause: BaseException | None = None) -> None:
126 super().__init__(message, cause)
129class SheetNotFoundError(EzXlError):
130 """Raised when a worksheet cannot be found by name in a workbook.
132 Args:
133 message: Human-readable description of the error.
134 cause: Original exception that triggered this error, if any.
136 Example:
137 >>> raise SheetNotFoundError("No sheet named 'Summary' in 'report.xlsx'")
138 """
140 def __init__(self, message: str, cause: BaseException | None = None) -> None:
141 super().__init__(message, cause)
144# ///////////////////////////////////////////////////////////////
145# COM OPERATION ERRORS
146# ///////////////////////////////////////////////////////////////
149class COMOperationError(EzXlError):
150 """Raised for unclassified COM errors that do not map to a specific subclass.
152 This is the catch-all wrapper for ``pywintypes.com_error`` exceptions.
153 If a COM error can be identified as a lost session or unavailability
154 issue, the more specific subclass should be used instead.
156 Args:
157 message: Human-readable description of the error.
158 cause: Original exception that triggered this error, if any.
159 """
161 def __init__(self, message: str, cause: BaseException | None = None) -> None:
162 super().__init__(message, cause)
165# ///////////////////////////////////////////////////////////////
166# GUI OPERATION ERRORS
167# ///////////////////////////////////////////////////////////////
170class GUIOperationError(EzXlError):
171 """Raised when a GUI-level COM operation fails for ribbon, menu, or dialog.
173 Distinct from ``COMOperationError`` to allow consumer code to
174 differentiate between generic COM failures and failures that occur
175 specifically within GUI interaction surfaces (ribbon, CommandBars,
176 file dialogs, message boxes).
178 Args:
179 message: Human-readable description of the error.
180 cause: Original exception that triggered this error, if any.
182 Example:
183 >>> raise GUIOperationError(
184 ... "Failed to execute ribbon command 'FileSave'", cause=exc
185 ... )
186 """
188 def __init__(self, message: str, cause: BaseException | None = None) -> None:
189 super().__init__(message, cause)
192# ///////////////////////////////////////////////////////////////
193# FORMATTER ERRORS
194# ///////////////////////////////////////////////////////////////
197class FormatterError(EzXlError):
198 """Raised when an openpyxl-based formatting operation fails.
200 This exception covers errors that occur during closed-file formatting
201 via ``ExcelFormatter``, such as invalid cell references, unsupported
202 style properties, or file I/O failures.
204 Args:
205 message: Human-readable description of the error.
206 cause: Original exception that triggered this error, if any.
207 """
209 def __init__(self, message: str, cause: BaseException | None = None) -> None:
210 super().__init__(message, cause)