Coverage for seedboxsync/front/apis/error.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-26 17:46 +0000

1# 

2# Copyright (C) 2015-2026 Guillaume Kulakowski <guillaume@kulakowski.fr> 

3# 

4# For the full copyright and license information, please view the LICENSE 

5# file that was distributed with this source code. 

6# 

7"""SeedboxSync api error module.""" 

8 

9from datetime import datetime 

10from typing import Any 

11import uuid 

12from flask import Response, jsonify 

13from flask_babel import gettext 

14from werkzeug.exceptions import BadRequest, HTTPException, NotFound 

15from seedboxsync.front.apis import api 

16 

17 

18@api.errorhandler(BadRequest) # type: ignore[untyped-decorator] 

19@api.errorhandler(NotFound) # type: ignore[untyped-decorator] 

20def api_errorhandler(error: BadRequest | NotFound) -> tuple[dict[str, Any], int]: 

21 """ 

22 Handle validation and not-found API errors. 

23 

24 Args: 

25 error (BadRequest | NotFound): HTTP exception to serialize. 

26 

27 Returns: 

28 tuple[dict[str, Any], int]: Empty response body and HTTP status code. 

29 """ 

30 status_code = error.code or 500 

31 

32 error.data = { # type: ignore[union-attr] 

33 "type": "about:blank", 

34 "success": False, 

35 "status": status_code, 

36 "title": error.data.get("message", ""), # type: ignore[union-attr] 

37 **({"message": error.data["errors"]} if "errors" in error.data else {}), # type: ignore[union-attr] 

38 "timestamp": datetime.now().astimezone().isoformat(), 

39 "traceId": str(uuid.uuid4()), 

40 } 

41 

42 return {}, status_code 

43 

44 

45def error(exc: Exception) -> tuple[Response, int | None]: 

46 """ 

47 Serialize an exception as a JSON API response. 

48 

49 Args: 

50 exc (Exception): Exception raised while processing the request. 

51 

52 Returns: 

53 tuple[Response, int | None]: JSON response and HTTP status code. 

54 """ 

55 status_code = exc.code if isinstance(exc, HTTPException) else 500 

56 title = exc.name if isinstance(exc, HTTPException) else gettext("Internal Server Error") 

57 message = exc.description if isinstance(exc, HTTPException) else str(exc) 

58 

59 return ( 

60 jsonify( 

61 { 

62 "type": "about:blank", 

63 "success": False, 

64 "status": status_code, 

65 "title": title, 

66 "message": message, 

67 "timestamp": datetime.now().astimezone().isoformat(), 

68 "traceId": str(uuid.uuid4()), 

69 } 

70 ), 

71 status_code, 

72 )