Coverage for nexios\handlers\not_found.py: 68%

1 import traceback

2 import typing

3 import http

4 from nexios.http import Request, Response

5 from nexios.config import get_config

6 from nexios.exceptions import NotFoundException

7

8

9 def generate_html_page(title: str, message: str) -> str:

10 """Generates a simple HTML page without using Jinja2."""

11 return f"""<!DOCTYPE html>

12<html lang="en">

13<head>

14 <meta charset="UTF-8">

15 <meta name="viewport" content="width=device-width, initial-scale=1.0">

16 <title>{title}</title>

17 <style>

18 body {

19 font-family: Arial, sans-serif;

20 text-align: center;

21 margin: 50px;

22 color: #333;

23 }

24 h1 {

25 font-size: 48px;

26 color: #d9534f;

27 }

28 p {

29 font-size: 18px;

30 margin-top: 10px;

31 }

32 </style>

33</head>

34<body>

35 <h1>{title}</h1>

36 <p>{message}</p>

37</body>

38</html>"""

39

40

41 async def handle_404_error(

42 request: Request,

43 response: Response,

44 exception: NotFoundException,

45) -> typing.Any:

46 """

47 Handles 404 errors dynamically, supporting JSON, HTML, and plain text responses.

48

49 Args:

50 request: The request object (not used here but kept for flexibility).

51 response: A callable that returns a response.

52 exception: The NotFoundException instance.

53 settings: A dictionary of settings to determine the response format.

54

55 Returns:

56 A response based on the settings.

57 """

58 settings = get_config()

59

60 debug = settings.debug or False

61 not_found_config = settings.not_fouund

62

63 if not_found_config:

64 return_json = not_found_config.return_json

65 custom_message = not_found_config.custom_message

66 show_traceback = not_found_config.show_traceback

67 use_html = not_found_config.use_html

68 else:

69 return_json = True

70 custom_message = "The page you are looking for does not exist."

71 show_traceback = False

72 use_html = True

73

74 error_message = exception.detail if debug else custom_message

75

76 if show_traceback and debug:

77 traceback_info = traceback.format_exc()

78 else:

79 traceback_info = None

80

81 if return_json:

82 error_details: typing.Dict[str, typing.Any] = {

83 "status": 404,

84 "error": http.HTTPStatus(404).phrase,

85 "message": error_message,

86 }

87 if traceback_info:

88 error_details["traceback"] = traceback_info

89

90 return response.json(error_details, status_code=404)

91

92 if use_html:

93 html_content = generate_html_page("404 - Not Found", error_message)

94 return response.html(html_content, status_code=404)

95

96 # Plain Text Fallback

97 return response.text(

98 f"404 - Not Found\n{error_message}",

99 )