Newer
Older

François Ferry
committed
import logging
from cubicweb import AuthenticationError, Forbidden, Unauthorized, QueryError
from pyramid.config import Configurator
from pyramid.request import Request
from rql import RQLException
from yams import ValidationError, UnknownType
from cubicweb_api.httperrors import get_http_error, get_http_500_error
from cubicweb_api.transaction import InvalidTransaction

François Ferry
committed
log = logging.getLogger(__name__)
class ApiException(Exception):

Frank Bessou
committed
def __init__(self, original_exception: Exception):

François Ferry
committed
self.original_exception = original_exception

François Ferry
committed
def api_exception_view(api_exception: ApiException, request: Request):

Frank Bessou
committed
wrapped_exception = api_exception.original_exception
exception_name = api_exception.original_exception.__class__.__name__
if isinstance(wrapped_exception, ValidationError):
wrapped_exception.translate(request.cw_cnx._)

François Ferry
committed
# RQL errors -> 400
if isinstance(

Frank Bessou
committed
wrapped_exception,
(ValidationError, QueryError, UnknownType, RQLException, InvalidTransaction),

François Ferry
committed
):

Frank Bessou
committed
return get_http_error(
400,
exception_name,
str(wrapped_exception),
)

François Ferry
committed
# Authentication and Unauthorized -> 401

Frank Bessou
committed
if isinstance(wrapped_exception, (AuthenticationError, Unauthorized)):
return get_http_error(
401,
exception_name,
str(wrapped_exception),
)

François Ferry
committed
# Forbidden -> 403

Frank Bessou
committed
if isinstance(wrapped_exception, Forbidden):
return get_http_error(
403,
exception_name,
str(wrapped_exception),
)

François Ferry
committed
# Default case -> 500

Frank Bessou
committed
log.exception(
f"Request to {request.path_qs} raised the following exception: ",
exc_info=wrapped_exception,
)

François Ferry
committed
return get_http_500_error()
def includeme(config: Configurator):
config.add_exception_view(api_exception_view, context=ApiException)