# GCM Diagnostics

Library for collecting errors from validation logic and presenting them to user.

Mainly intended to be used with FastAPI endpoints for doing business validation which Pydantic is not intended for. Errors
generated by this library are compatible with Pydantic validation response, so it appears the same
to the consumer of API.

## Installation

```bash
pip install gcm_diagnostics
```

## Usage

```python
from gcm_diagnostics import DiagnosticCollector
from gcm_diagnostics.errors import EntityNotFound, EntityAlreadyExists

with DiagnosticCollector(prefix=["body"]) as diag:
    diag.append(EntityNotFound(loc=[1, "id"], id=1))
    diag.append(EntityAlreadyExists(loc=[2, "name"], entity="Hello"))

# Here, DiagnosticException is raised, containing both errors.

print(diag.errors)
# [
#     {
#         "loc": ["body", 1, "id"],
#         "msg": "Entity with id 1 not found",
#         "type": "entity_not_found",
#         "id": 1
#     },
#     {
#         "loc": ["body", 2, "name"],
#         "msg": "Entity already exists",
#         "type": "entity_already_exists",
#         "entity": "Hello"
#     }
# ]
```

## Usage with FastAPI

```python
from fastapi import FastAPI
from gcm_diagnostics import install_exception_handler, DiagnosticCollector
from gcm_diagnostics.errors import EntityNotFound
from starlette.testclient import TestClient

app = FastAPI()
install_exception_handler(app)

@app.get("/")
def diagnostics(id: int):
    with DiagnosticCollector(prefix=["query"]) as diag:
        diag.append(EntityNotFound(loc=["id"], id=id))


with TestClient(app, raise_server_exceptions=False) as client:
    response = client.get("/", params={"id": 123})
    assert response.status_code == 404
    assert response.json() == {
        "detail": [
            {
                "loc": ["query", "id"],
                "msg": "Entity does not exists.",
                "type": "entity_not_found",
                "id": 123
            }
        ]
    }
```

For more usage details, please consult the documentation in the code, mainly the documentation of class `DiagnosticCollector`.

## Maturity

This library is currently used in various production applications and is considered stable.

## Contributing

Contributions are always welcome. Just open an issue or a merge request.
