Metadata-Version: 2.4
Name: mobius-error-lib
Version: 1.0.0
Summary: Standard exception handling library for Mobius Python microservices
Author: Mobius Platform Team
License: MIT
Project-URL: Homepage, https://github.com/aidtaas/mobius-error-lib-python
Project-URL: Documentation, https://mobiusdtaas.atlassian.net/wiki/spaces/EN/pages/2360868868
Project-URL: Repository, https://github.com/aidtaas/mobius-error-lib-python
Keywords: fastapi,exceptions,error-handling,mobius,microservices
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Framework :: FastAPI
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: fastapi>=0.100.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: httpx>=0.24; extra == "dev"
Requires-Dist: uvicorn>=0.22; extra == "dev"

# mobius-error-lib

> Standard exception handling library for **Mobius Python microservices**.  
> Mirrors the Java `error-spring-lib` — consistent error format across all services.

---

## Installation

```bash
pip install mobius-error-lib
```

---

## Standard Error Response Format

Every exception thrown produces this JSON:

```json
{
    "timestamp": 1774259394599,
    "origin": "my-python-service",
    "errorCode": 404000,
    "errorMessage": "The requested resource does not exist.",
    "subErrors": [
        {
            "message": "User with id 123 not found",
            "actionRequired": "Please provide a valid user ID",
            "timestamp": 1774259394
        }
    ],
    "actionsRequired": [
        "Please provide a valid resource ID"
    ],
    "httpStatusCode": "NOT_FOUND",
    "docUrl": "https://mobiusdtaas.atlassian.net/wiki/..."
}
```

---

## Quick Start (FastAPI)

```python
from fastapi import FastAPI
from mobius_error_lib import (
    register_exception_handlers,
    set_app_name,
    ApiException,
    CommonErrors,
)

app = FastAPI()

# Set your service name (shows in "origin" field of every error)
set_app_name("my-python-service")

# Register all exception handlers — one line!
register_exception_handlers(app)


@app.get("/users/{user_id}")
def get_user(user_id: str):
    user = db.find(user_id)
    if not user:
        raise ApiException(
            CommonErrors.RESOURCE_NOT_FOUND,
            f"User with id {user_id} not found"
        )
    return user
```

---

## Exception Types

| Exception | HTTP Status | Use Case |
|---|---|---|
| `ApiException` | From Error def | Base — all custom exceptions |
| `ApplicationException` | 403 | App-level failures |
| `ValidationException` | 409 | Input validation errors |
| `AccessViolationException` | 403 | Unauthorized access |
| `DataTypeMismatchException` | 400 | Type mismatch in request |
| `TokenException` | 401 | JWT / auth token errors |
| `KafkaException` | 400 | Kafka publish/consume errors |
| `RestException` | 500 | REST client failures |

---

## Using CommonErrors

Pre-defined errors ready to use:

```python
from mobius_error_lib import CommonErrors, ApiException, ValidationException, AccessViolationException

# 404
raise ApiException(CommonErrors.RESOURCE_NOT_FOUND, "Dataverse not found")

# 403
raise AccessViolationException(CommonErrors.INVALID_TENANT_ID)

# 409
raise ValidationException(CommonErrors.CONSTRAINT_VIOLATION, "Name already exists")

# 500
raise ApiException(CommonErrors.UNEXPECTED_ERROR)
```

---

## Defining Custom Errors (Service-Specific)

Mirror the Java pattern — define your own Error constants:

```python
from mobius_error_lib import Error, HttpStatus, ApiException

class PICommonErrors:
    DATAVERSE_NOT_FOUND = Error(
        http_status_code=HttpStatus.NOT_FOUND,
        error_code=404001,
        error_message="Dataverse does not exist.",
        action_required="Please create the dataverse first.",
    )

    DELETION_NOT_ALLOWED = Error(
        http_status_code=HttpStatus.FORBIDDEN,
        error_code=403010,
        error_message="Deletion is not allowed.",
        action_required="Please confirm delete by setting confirmDelete=true",
    )


# Usage — exactly like Java!
raise ApiException(
    PICommonErrors.DELETION_NOT_ALLOWED,
    "Please confirm delete by setting true"
)
```

---

## Adding SubErrors and Actions

```python
from mobius_error_lib import ApiException, ErrorMessage, CommonErrors

exc = ApiException(CommonErrors.RESOURCE_NOT_FOUND, "Dataverse not found")
exc.add_sub_error(ErrorMessage(
    message="Dataverse with id: 689adb47 and version: 1 not found",
    action_required="Please provide a valid dataverseId and version."
))
exc.add_action_required("Please create the dataverse first.")
raise exc
```

---

## PyPI Publishing

```bash
# Install build tools
pip install build twine

# Build
python -m build

# Upload to PyPI
twine upload dist/*
```

---

## Exception Hierarchy

```
Exception
└── ApiException
    ├── TokenException (401)
    └── ApplicationException (403)
        ├── ValidationException (409)
        │   └── AccessViolationException (403)
        ├── DataTypeMismatchException (400)
        ├── KafkaException (400)
        ├── ObjectMappingException (500)
        └── RestException (500)
```
