You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+26-3Lines changed: 26 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -2,20 +2,43 @@
2
2
3
3
## [1.0.0] - 2024-04-26
4
4
5
+
Changes:
6
+
5
7
- First release on PyPI
6
8
7
9
## [1.0.1] - 2024-04-30
8
10
11
+
Changes:
12
+
9
13
- Upgrade dependencies
10
14
11
15
## [1.0.2] - 2024-09-08
12
16
13
-
- Add docstrings to handlers
17
+
Changes:
18
+
19
+
- Add docstrings
14
20
- Improve Makefile
15
21
- Improve README
16
22
17
23
## [1.0.3] - 2025-03-16
18
24
19
-
- Update README
20
-
- Improve tests
25
+
Changes:
26
+
21
27
- Fix DRF API settings initialization
28
+
- Improve tests
29
+
- Update README
30
+
31
+
## [2.0.0] - 2025-07-11
32
+
33
+
Breaking changes:
34
+
35
+
- The API error response now **always** includes the keys: `title`, `detail`, and `invalid_param`. The `title` key is always populated, while `detail` and `invalid_param` may be `null` depending on the error source.
A library for [Django Rest Framework](https://www.django-rest-framework.org/) returning **consistent, predictable and easy-to-parse API error messages**.
11
11
12
-
This library was built with [RFC7807](https://tools.ietf.org/html/rfc7807) guidelines in mind, but with a small twist: it defines a "problem detail" as a list, but it still serves as a way to include errors in a predictable and easy-to-parse format for any API consumer. Error messages are formatted using RFC7807 keywords and DRF exception data.
12
+
This library was built with [RFC7807](https://tools.ietf.org/html/rfc7807) guidelines in mind, but with a small twist: it defines a "problem detail" as a list instead of a string, but it still serves as a way to include errors in a human-readable and easy-to-parse format for any API consumer.
13
+
Error messages are formatted using RFC7807 keywords and DRF exception data.
14
+
15
+
Unlike standard DRF, where the error response format varies depending on the error source, this library always returns errors in a consistent and predictable structure.
13
16
14
17
## What's different?
15
18
16
19
Compared to other similar and popular libraries, this library:
17
20
18
21
- Is based on RFC7807 guidelines
19
22
- Aims to provide not only a standardized format for error details, but also human-readable error messages (perfect for both internal and public APIs)
20
-
- Transforms both `django.core.exceptions.ValidationError` and `rest_framework.errors.ValidationError` to API errors, so you don't have to handle error raised by services/domain logic, `clean()`, or other functions/methods
23
+
- Transforms both `django.core.exceptions.ValidationError` and `rest_framework.errors.ValidationError` to API errors, so you don't have to handle error raised by services/domain logic, `clean()`, etc.
21
24
22
25
## Table of Contents
23
26
@@ -57,13 +60,13 @@ REST_FRAMEWORK = {
57
60
58
61
### Error structure overview
59
62
60
-
API error messages typically include the following keys:
63
+
API error messages will include the following keys:
61
64
62
-
-`"title"` (`str`): A brief summary that describes the problem type
63
-
-`"detail"` (`list[str] | None`): A list of specific explanations related to the problem
64
-
-`"invalid_params"` (`list[dict] | None`): A list of dict containing details about parameters that were invalid or malformed in the request. Each dict within this list provides:
65
-
-`"name"` (`str`): The name of the parameter that was found to be invalid
66
-
-`"reasons"` (`list[str]`): A list of strings describing the specific reasons why the parameter was considered invalid or malformed
65
+
-`"title"` (`str`): A brief summary that describes the problem type.
66
+
-`"detail"` (`list[str] | None`): A list of specific explanations related to the problem, if any.
67
+
-`"invalid_params"` (`list[dict] | None`): A list of dict containing details about parameters that were invalid or malformed in the request, if any. Each dict within this list provides:
68
+
-`"name"` (`str`): The name of the parameter that was found to be invalid.
69
+
-`"reasons"` (`list[str]`): A list of strings describing the specific reasons why the parameter was considered invalid or malformed.
67
70
68
71
```json
69
72
{
@@ -91,17 +94,18 @@ API error messages typically include the following keys:
91
94
92
95
```json
93
96
{
94
-
"title": "Error message.",
95
-
"invalid_params": [
96
-
{
97
-
"name": "field_name",
98
-
"reason": [
99
-
"error",
100
-
...
101
-
]
102
-
},
103
-
...
104
-
]
97
+
"title": "Error message.",
98
+
"details": null,
99
+
"invalid_params": [
100
+
{
101
+
"name": "field_name",
102
+
"reason": [
103
+
"error"
104
+
// ...
105
+
]
106
+
}
107
+
// ...
108
+
]
105
109
}
106
110
```
107
111
@@ -111,23 +115,26 @@ API error messages typically include the following keys:
111
115
{
112
116
"title": "Error message.",
113
117
"detail": [
114
-
"error",
115
-
...
116
-
]
118
+
"error"
119
+
// ...
120
+
],
121
+
"invalid_params": null
117
122
}
118
123
```
119
124
120
125
#### Other bad requests with no detail
121
126
122
127
```json
123
128
{
124
-
"title": "Error message."
129
+
"title": "Error message.",
130
+
"detail": null,
131
+
"invalid_params": null
125
132
}
126
133
```
127
134
128
135
## Settings
129
136
130
-
Default available settings:
137
+
Default settings:
131
138
132
139
```python
133
140
DRF_SIMPLE_API_ERRORS= {
@@ -146,15 +153,16 @@ If `CAMELIZE` is set to `True`:
146
153
```json
147
154
{
148
155
"title": "Error message.",
156
+
"details": null,
149
157
"invalidParams": [
150
158
{
151
159
"name": "fieldName",
152
160
"reason": [
153
-
"error",
154
-
...
161
+
"error"
162
+
// ...
155
163
]
156
164
}
157
-
...
165
+
// ...
158
166
]
159
167
}
160
168
```
@@ -163,89 +171,23 @@ If `CAMELIZE` is set to `True`:
163
171
164
172
Support for exceptions that differ from the standard structure of the Django Rest Framework.
165
173
166
-
For instance, you may want to specify you own exception:
For example, if you need to customize how a specific exception is handled or want to format an existing exception differently, you can create your own handler.
207
175
208
-
```python
209
-
AuthenticationFailed(
210
-
{
211
-
"detail": "Error message.",
212
-
"messages": [
213
-
{
214
-
"metadata": "metadata_data",
215
-
"type": "type_name",
216
-
"message": "error message",
217
-
}
218
-
],
219
-
}
220
-
)
221
-
```
222
-
223
-
You can handle this by creating a `handlers.py` file and specifying an handler for your use case:
224
-
225
-
```python
226
-
defhandle_exc_custom_authentication_failed(exc):
227
-
from path.to.my.exceptions import AuthenticationFailed
228
-
229
-
ifisinstance(exc, AuthenticationFailed):
230
-
try:
231
-
exc.detail = exc.detail["messages"][0]["message"]
232
-
except (KeyError, IndexError):
233
-
exc.detail = exc.detail["detail"]
234
-
235
-
return exc
236
-
```
176
+
To customize error handling for your project, simply create a new file (for example, `extra_handlers.py`) and define your own handler functions. This approach lets you tailor error responses to fit your specific needs.
237
177
238
178
Then add it to the `EXTRA_HANDLERS` list in this package settings:
0 commit comments