|
2 | 2 |
|
3 | 3 | ## Errors in Tasks |
4 | 4 |
|
5 | | -All uncaught exceptions in a task are treated as fatal exceptions. The task is then marked as |
6 | | -failed. The error traceback, description, and code are returned to the user under the |
7 | | -`pulpcore.app.models.Task.error` attribute of the `pulpcore.app.models.Task` |
8 | | -object. |
| 5 | +All uncaught exceptions in a task are treated as fatal exceptions and the task is marked as failed. |
| 6 | +The error description and error code are stored in the `error` attribute of the `pulpcore.app.models.Task` object and returned to the user. |
9 | 7 |
|
10 | | -When raising exceptions [built-in Python Exceptions](https://docs.python.org/3/library/exceptions.html) |
11 | | -should be used if possible. {doc}`Coded Exceptions </contributing/platform-api/exceptions>` should be used for known error situations. |
| 8 | +!!! warning "Security: Tracebacks Are Not Returned" |
| 9 | + To prevent information disclosure, **exception tracebacks are logged server-side but are |
| 10 | + NOT stored in the task or returned to API users**. |
| 11 | + This prevents sensitive information (URLs, credentials, file paths) from being exposed through the API. |
| 12 | + |
| 13 | +## Exception Types |
| 14 | + |
| 15 | +### Standard Python Exceptions |
| 16 | + |
| 17 | +For programming errors and standard error scenarios, use [built-in Python exceptions](https://docs.python.org/3/library/exceptions.html) |
| 18 | +(e.g., `ValueError`, `TypeError`, `KeyError`). |
| 19 | +These are appropriate for logic errors and invalid inputs. |
| 20 | + |
| 21 | +### PulpException - Base Class for Domain Errors |
| 22 | + |
| 23 | +For known Pulp-specific error scenarios (timeouts, authentication failures, validation errors), |
| 24 | +use exceptions that inherit from `pulpcore.exceptions.PulpException`. |
| 25 | +Each PulpException: |
| 26 | + |
| 27 | +- Has a unique **error code** (e.g., `PLP0005`) |
| 28 | +- Has an associated **HTTP status code** (defaults to 500) |
| 29 | +- Implements a user-safe `__str__()` method that includes the error code in `[PLP####]` format followed by a description without sensitive data |
| 30 | + |
| 31 | +When a `PulpException` is raised in a task, the error message (including the error code) and description are returned to the user. |
| 32 | +Tracebacks are logged but never exposed through the API. |
| 33 | + |
| 34 | +!!! note "Error Code Reference" |
| 35 | + For a complete list of all Pulp error codes and their meanings, see the [Pulp Errors](site:pulpcore/docs/user/reference/pulp-errors/) user documentation. |
| 36 | + |
| 37 | +## Using PulpException in Code |
| 38 | + |
| 39 | +Below are implementation examples for the available PulpExceptions. |
| 40 | + |
| 41 | +### PLP0000 - InternalErrorException |
| 42 | + |
| 43 | +Signals an unexpected internal error. |
| 44 | +This is raised automatically by the task system when an uncaught exception occurs that is not a `PulpException`. |
| 45 | + |
| 46 | +**Usage in code:** |
| 47 | +```python |
| 48 | +safe_exc = InternalErrorException() |
| 49 | +task.set_failed(safe_exc) |
| 50 | +``` |
| 51 | + |
| 52 | +**When used:** Automatically raised by the task system for unexpected errors (equivalent of HTTP 500). |
| 53 | + |
| 54 | +--- |
| 55 | + |
| 56 | +### PLP0002 - MissingPlugin |
| 57 | + |
| 58 | +Raised when a requested plugin is not installed. |
| 59 | + |
| 60 | +**Usage in code:** |
| 61 | +```python |
| 62 | +raise MissingPlugin(plugin_app_label) |
| 63 | +``` |
| 64 | + |
| 65 | +--- |
| 66 | + |
| 67 | +### PLP0003 - DigestValidationError |
| 68 | + |
| 69 | +Raised when a file fails digest/checksum validation during download or artifact validation. |
| 70 | + |
| 71 | +**Usage in code:** |
| 72 | +```python |
| 73 | +raise DigestValidationError(actual_digest, expected_digest, url=self.url) |
| 74 | +``` |
| 75 | + |
| 76 | +--- |
| 77 | + |
| 78 | +### PLP0004 - SizeValidationError |
| 79 | + |
| 80 | +Raised when a file fails size validation during download or artifact validation. |
| 81 | + |
| 82 | +**Usage in code:** |
| 83 | +```python |
| 84 | +raise SizeValidationError(actual_size, expected_size, url=self.url) |
| 85 | +``` |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +### PLP0005 - TimeoutException |
| 90 | + |
| 91 | +Raised when a download or network request times out. |
| 92 | + |
| 93 | +**Usage in code:** |
| 94 | +```python |
| 95 | +raise TimeoutException(self.url) |
| 96 | +``` |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +### PLP0006 - ResourceImmutableError |
| 101 | + |
| 102 | +Raised when attempting to modify an immutable resource (e.g., a published repository version). |
| 103 | + |
| 104 | +**Usage in code:** |
| 105 | +```python |
| 106 | +raise ResourceImmutableError(self) |
| 107 | +``` |
| 108 | + |
| 109 | +--- |
| 110 | + |
| 111 | +### PLP0007 - DomainProtectedError |
| 112 | + |
| 113 | +Raised when attempting to delete a domain that still contains repositories with content. |
| 114 | + |
| 115 | +**Usage in code:** |
| 116 | +```python |
| 117 | +raise DomainProtectedError() |
| 118 | +``` |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +### PLP0008 - DnsDomainNameException |
| 123 | + |
| 124 | +Raised when DNS resolution fails for a URL during download operations. |
| 125 | + |
| 126 | +**Usage in code:** |
| 127 | +```python |
| 128 | +raise DnsDomainNameException(self.url) |
| 129 | +``` |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +### PLP0009 - UrlSchemeNotSupportedError |
| 134 | + |
| 135 | +Raised when an unsupported URL scheme is provided (e.g., `ftp://` when only `http://` and `https://` are supported). |
| 136 | + |
| 137 | +**Usage in code:** |
| 138 | +```python |
| 139 | +raise UrlSchemeNotSupportedError(url) |
| 140 | +``` |
| 141 | + |
| 142 | +--- |
| 143 | + |
| 144 | +### PLP0010 - ProxyAuthenticationError |
| 145 | + |
| 146 | +Raised when proxy authentication fails (HTTP 407 response from proxy server). |
| 147 | + |
| 148 | +**Usage in code:** |
| 149 | +```python |
| 150 | +raise ProxyAuthenticationError(self.proxy) |
| 151 | +``` |
| 152 | + |
| 153 | +--- |
| 154 | + |
| 155 | +### PLP0011 - RepositoryVersionDeleteError |
| 156 | + |
| 157 | +Raised when attempting to delete a repository version when it's the only version remaining. |
| 158 | + |
| 159 | +**Usage in code:** |
| 160 | +```python |
| 161 | +raise RepositoryVersionDeleteError() |
| 162 | +``` |
0 commit comments