Coverage for src/lexigram/admin/controllers/error.py: 0%

29 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-24 23:18 +0800

1"""Error handler controller for Lexigram Admin. 

2 

3Provides user-friendly error pages for common HTTP errors. 

4""" 

5 

6from __future__ import annotations 

7 

8from starlette.requests import Request 

9from starlette.responses import HTMLResponse, RedirectResponse 

10 

11from lexigram.admin.controllers.base import AdminController 

12from lexigram.admin.engine.renderer import AdminRenderer 

13from lexigram.admin.lib.template import render_error_page 

14from lexigram.contracts.web import get 

15from lexigram.di.decorators import inject 

16 

17 

18@inject 

19class ErrorController(AdminController): 

20 """Error page controller. 

21 

22 Provides styled error pages for: 

23 - 401 Unauthorized - Redirects to login 

24 - 403 Forbidden - Access denied 

25 - 404 Not Found - Page not found 

26 - 500 Internal Server Error - Server error 

27 """ 

28 

29 prefix = "/admin/error" 

30 

31 def __init__(self, renderer: AdminRenderer): 

32 super().__init__(renderer) 

33 

34 def _render_error_page( 

35 self, 

36 status_code: int, 

37 title: str, 

38 message: str, 

39 icon: str, 

40 action_text: str = "Go to Dashboard", 

41 action_url: str = "/admin/", 

42 ) -> HTMLResponse: 

43 """Render a styled error page using templates. 

44 

45 Args: 

46 status_code: HTTP status code 

47 title: Error title 

48 message: Error message 

49 icon: Emoji icon 

50 action_text: Button text 

51 action_url: Button URL 

52 

53 Returns: 

54 HTMLResponse with styled error page 

55 """ 

56 html = render_error_page( 

57 status_code=status_code, 

58 title=title, 

59 message=message, 

60 icon=icon, 

61 action_text=action_text, 

62 action_url=action_url, 

63 ) 

64 return HTMLResponse(content=html, status_code=status_code) 

65 

66 @get("/401") 

67 async def error_401(self, request: Request) -> RedirectResponse: 

68 """Handle 401 Unauthorized - redirect to login.""" 

69 # Get the original URL for redirect after login 

70 next_url = request.query_params.get("next", "/admin/") 

71 return RedirectResponse(url=f"/admin/login?next={next_url}", status_code=302) 

72 

73 @get("/403") 

74 async def error_403(self, request: Request) -> HTMLResponse: 

75 """Handle 403 Forbidden.""" 

76 return self._render_error_page( 

77 status_code=403, 

78 title="Access Denied", 

79 message="You don't have permission to access this resource. Please contact your administrator if you believe this is an error.", 

80 icon="🔒", 

81 ) 

82 

83 @get("/404") 

84 async def error_404(self, request: Request) -> HTMLResponse: 

85 """Handle 404 Not Found.""" 

86 return self._render_error_page( 

87 status_code=404, 

88 title="Page Not Found", 

89 message="The page you're looking for doesn't exist. It may have been moved or deleted.", 

90 icon="🔍", 

91 ) 

92 

93 @get("/500") 

94 async def error_500(self, request: Request) -> HTMLResponse: 

95 """Handle 500 Internal Server Error.""" 

96 return self._render_error_page( 

97 status_code=500, 

98 title="Internal Server Error", 

99 message="Something went wrong on our end. Our team has been notified and we're working to fix it.", 

100 icon="⚠️", 

101 )