web_error


Nameweb_error JSON
Version 0.6.10 PyPI version JSON
download
home_pagehttps://github.com/EdgyEdgemond/web-error/
SummaryWeb based error utils
upload_time2024-04-11 11:26:38
maintainerNone
docs_urlNone
authorDaniel Edgecombe
requires_python<4.0,>=3.9
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Web Errors v0.6.10
[![image](https://img.shields.io/pypi/v/web_error.svg)](https://pypi.org/project/web_error/)
[![image](https://img.shields.io/pypi/l/web_error.svg)](https://pypi.org/project/web_error/)
[![image](https://img.shields.io/pypi/pyversions/web_error.svg)](https://pypi.org/project/web_error/)
![style](https://github.com/NRWLDev/web-error/actions/workflows/style.yml/badge.svg)
![tests](https://github.com/NRWLDev/web-error/actions/workflows/tests.yml/badge.svg)
[![codecov](https://codecov.io/gh/NRWLDev/web-error/branch/main/graph/badge.svg)](https://codecov.io/gh/NRWLDev/web-error)

`web_error` is a set of exceptions and handlers for use in starlette/fastapi
applications to support easy error management and responses

Each exception easily marshals to JSON based on the
[RFC9457](https://www.rfc-editor.org/rfc/rfc9457.html) spec for use in api
errors.

## Migrating to 0.6 (RFC9457 support)

Check the discussion [here](github.com/EdgyEdgemond/web-error/discussions/22)
for details on how to update usage to maintain legacy functionality or move over
to problem details support.

## Errors

The base `web_error.error.HttpException` accepts a `title`, `details`, `status`
(default 500) and optional `**kwargs`. An additional `code` can be passed in,
which will be used as the `type`, if not provided the `type` is derived from
the class name.

And will return a JSON response with `exc.status` as the status code and response body:

```json
{
    "type": "an-exception",
    "title": "title",
    "details": "details",
    "status": 500,
    "extra-key": "extra-value",
    ...
}
```

Derived types are generated using the class name after dropping `...Error` from
the end, and converting to `kebab-case`. i.e. `PascalCaseError` will derive the
type `pascal-case`. If the class name doesn't suit your purposes, an optional
`code` attribute can be set with the desired value of there response `type`
field.

Some convenience Exceptions are provided with predefined `status` attributes.
To create custom errors subclasss these and define the `title` attribute.

* `web_error.error.ServerException` provides status 500 errors
* `web_error.error.BadRequestException` provides status 400 errors
* `web_error.error.UnauthorisedException` provides status 401 errors
* `web_error.error.NotFoundException` provides status 404 errors

### Custom Errors

Subclassing the convenience classes provide a simple way to consistently raise the same error
with details/extras changing based on the raised context.

```python
from web_error.error import NotFoundException


class UserNotFoundError(NotFoundException):
    title = "User not found."

raise UserNotFoundError(details="details")
```

```json
{
    "type": "user-not-found",
    "title": "User not found",
    "details": "details",
    "status": 404,
}
```

Whereas a defined `code` will be used in the output.

```python
class UserNotFoundError(NotFoundException):
    title = "User not found."
    code = "cant-find-user"

raise UserNotFoundError(details="details")
```

```json
{
    "type": "cant-find-user",
    "title": "User not found",
    "details": "details",
    "status": 404,
}
```

If additional kwargs are provided when the error is raised, they will be
included in the output (ensure the provided values are json seriablizable.


```python
raise UserNotFoundError(details="details", user_id="1234", metadata={"hello": "world"})
```

```json
{
    ...
    "details": "details",
    "user_id": "1234",
    "metadata": {"hello": "world"},
}
```

## Starlette


```python
    import starlette.applications
    import web_error.handler.starlette

    app = starlette.applications.Starlette()

    web_error.handler.starlette.add_exception_handler(app)
```

A custom logger can be provided to `add_exception_handler(app, logger=...)`.

If you require cors headers, you can pass a `web_error.cors.CorsConfiguration`
instance to `add_exception_handler(cors=...)`.

```python
add_exception_handler(
    app,
    cors=CorsConfiguration(
        allow_origins=["*"],
        allow_methods=["*"],
        allow_headers=["*"],
        allow_credentials=True,
    )
)
```

To handle unexpected errors provide `unhandled_wrappers`, a dict mapping http
status code to `HttpCodeException`, the system key `default` is also accepted
as the root wrapper for all unhandled exceptions.

If you wish to hide debug messaging from external users, `strip_debug=True`
will log the debug message and remove it from the response.

```python
    from web_error.error import HttpCodeException

    class NotFoundError(HttpCodeException):
        status = 404
        message = "Endpoint not found."

    web_error.handler.starlette.add_exception_handler(
        app,
        unhandled_wrappers={
            "404": NotFoundError,
        },
    )
```

## FastAPI

The FastAPI handler is identical to the starlette handler with the additional
handling of `RequestValidationError`.

```python
    import fastapi
    import web_error.handler.fastapi


    app = fastapi.FastAPI()
    web_error.handler.fastapi.add_exception_handler(app)
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/EdgyEdgemond/web-error/",
    "name": "web_error",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": "Daniel Edgecombe",
    "author_email": "edgy.edgemond@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/f5/48/337db1b2ef1553bd892eb70f44a1b164a1ab79cf7a5ec2e38695b202d4b0/web_error-0.6.10.tar.gz",
    "platform": null,
    "description": "# Web Errors v0.6.10\n[![image](https://img.shields.io/pypi/v/web_error.svg)](https://pypi.org/project/web_error/)\n[![image](https://img.shields.io/pypi/l/web_error.svg)](https://pypi.org/project/web_error/)\n[![image](https://img.shields.io/pypi/pyversions/web_error.svg)](https://pypi.org/project/web_error/)\n![style](https://github.com/NRWLDev/web-error/actions/workflows/style.yml/badge.svg)\n![tests](https://github.com/NRWLDev/web-error/actions/workflows/tests.yml/badge.svg)\n[![codecov](https://codecov.io/gh/NRWLDev/web-error/branch/main/graph/badge.svg)](https://codecov.io/gh/NRWLDev/web-error)\n\n`web_error` is a set of exceptions and handlers for use in starlette/fastapi\napplications to support easy error management and responses\n\nEach exception easily marshals to JSON based on the\n[RFC9457](https://www.rfc-editor.org/rfc/rfc9457.html) spec for use in api\nerrors.\n\n## Migrating to 0.6 (RFC9457 support)\n\nCheck the discussion [here](github.com/EdgyEdgemond/web-error/discussions/22)\nfor details on how to update usage to maintain legacy functionality or move over\nto problem details support.\n\n## Errors\n\nThe base `web_error.error.HttpException` accepts a `title`, `details`, `status`\n(default 500) and optional `**kwargs`. An additional `code` can be passed in,\nwhich will be used as the `type`, if not provided the `type` is derived from\nthe class name.\n\nAnd will return a JSON response with `exc.status` as the status code and response body:\n\n```json\n{\n    \"type\": \"an-exception\",\n    \"title\": \"title\",\n    \"details\": \"details\",\n    \"status\": 500,\n    \"extra-key\": \"extra-value\",\n    ...\n}\n```\n\nDerived types are generated using the class name after dropping `...Error` from\nthe end, and converting to `kebab-case`. i.e. `PascalCaseError` will derive the\ntype `pascal-case`. If the class name doesn't suit your purposes, an optional\n`code` attribute can be set with the desired value of there response `type`\nfield.\n\nSome convenience Exceptions are provided with predefined `status` attributes.\nTo create custom errors subclasss these and define the `title` attribute.\n\n* `web_error.error.ServerException` provides status 500 errors\n* `web_error.error.BadRequestException` provides status 400 errors\n* `web_error.error.UnauthorisedException` provides status 401 errors\n* `web_error.error.NotFoundException` provides status 404 errors\n\n### Custom Errors\n\nSubclassing the convenience classes provide a simple way to consistently raise the same error\nwith details/extras changing based on the raised context.\n\n```python\nfrom web_error.error import NotFoundException\n\n\nclass UserNotFoundError(NotFoundException):\n    title = \"User not found.\"\n\nraise UserNotFoundError(details=\"details\")\n```\n\n```json\n{\n    \"type\": \"user-not-found\",\n    \"title\": \"User not found\",\n    \"details\": \"details\",\n    \"status\": 404,\n}\n```\n\nWhereas a defined `code` will be used in the output.\n\n```python\nclass UserNotFoundError(NotFoundException):\n    title = \"User not found.\"\n    code = \"cant-find-user\"\n\nraise UserNotFoundError(details=\"details\")\n```\n\n```json\n{\n    \"type\": \"cant-find-user\",\n    \"title\": \"User not found\",\n    \"details\": \"details\",\n    \"status\": 404,\n}\n```\n\nIf additional kwargs are provided when the error is raised, they will be\nincluded in the output (ensure the provided values are json seriablizable.\n\n\n```python\nraise UserNotFoundError(details=\"details\", user_id=\"1234\", metadata={\"hello\": \"world\"})\n```\n\n```json\n{\n    ...\n    \"details\": \"details\",\n    \"user_id\": \"1234\",\n    \"metadata\": {\"hello\": \"world\"},\n}\n```\n\n## Starlette\n\n\n```python\n    import starlette.applications\n    import web_error.handler.starlette\n\n    app = starlette.applications.Starlette()\n\n    web_error.handler.starlette.add_exception_handler(app)\n```\n\nA custom logger can be provided to `add_exception_handler(app, logger=...)`.\n\nIf you require cors headers, you can pass a `web_error.cors.CorsConfiguration`\ninstance to `add_exception_handler(cors=...)`.\n\n```python\nadd_exception_handler(\n    app,\n    cors=CorsConfiguration(\n        allow_origins=[\"*\"],\n        allow_methods=[\"*\"],\n        allow_headers=[\"*\"],\n        allow_credentials=True,\n    )\n)\n```\n\nTo handle unexpected errors provide `unhandled_wrappers`, a dict mapping http\nstatus code to `HttpCodeException`, the system key `default` is also accepted\nas the root wrapper for all unhandled exceptions.\n\nIf you wish to hide debug messaging from external users, `strip_debug=True`\nwill log the debug message and remove it from the response.\n\n```python\n    from web_error.error import HttpCodeException\n\n    class NotFoundError(HttpCodeException):\n        status = 404\n        message = \"Endpoint not found.\"\n\n    web_error.handler.starlette.add_exception_handler(\n        app,\n        unhandled_wrappers={\n            \"404\": NotFoundError,\n        },\n    )\n```\n\n## FastAPI\n\nThe FastAPI handler is identical to the starlette handler with the additional\nhandling of `RequestValidationError`.\n\n```python\n    import fastapi\n    import web_error.handler.fastapi\n\n\n    app = fastapi.FastAPI()\n    web_error.handler.fastapi.add_exception_handler(app)\n```\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Web based error utils",
    "version": "0.6.10",
    "project_urls": {
        "Homepage": "https://github.com/EdgyEdgemond/web-error/",
        "Repository": "https://github.com/EdgyEdgemond/web-error/"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e0ef50dbb14c4ea6592dcbc729c722a472621d78f9fc342a4a703ef8093fa052",
                "md5": "3164d6b6b38805d689366c23de2e4175",
                "sha256": "953ea3aba751375141ec7c87e7448fc5e2389edf7c4b28e166fd4da129d0e8e9"
            },
            "downloads": -1,
            "filename": "web_error-0.6.10-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3164d6b6b38805d689366c23de2e4175",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 13100,
            "upload_time": "2024-04-11T11:26:36",
            "upload_time_iso_8601": "2024-04-11T11:26:36.674956Z",
            "url": "https://files.pythonhosted.org/packages/e0/ef/50dbb14c4ea6592dcbc729c722a472621d78f9fc342a4a703ef8093fa052/web_error-0.6.10-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f548337db1b2ef1553bd892eb70f44a1b164a1ab79cf7a5ec2e38695b202d4b0",
                "md5": "03da053d4fe8584f0d3418edc9ecde30",
                "sha256": "44bfac089644e970ebb29e5206741720d497f5ee62307d89be1c59b66e72969f"
            },
            "downloads": -1,
            "filename": "web_error-0.6.10.tar.gz",
            "has_sig": false,
            "md5_digest": "03da053d4fe8584f0d3418edc9ecde30",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 12154,
            "upload_time": "2024-04-11T11:26:38",
            "upload_time_iso_8601": "2024-04-11T11:26:38.309286Z",
            "url": "https://files.pythonhosted.org/packages/f5/48/337db1b2ef1553bd892eb70f44a1b164a1ab79cf7a5ec2e38695b202d4b0/web_error-0.6.10.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-11 11:26:38",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "EdgyEdgemond",
    "github_project": "web-error",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "web_error"
}
        
Elapsed time: 0.21353s