1from __future__ import annotations
2
3from collections.abc import Callable
4from typing import Any
5
6from plain.http import Request, ResponseBase
7from plain.templates import TemplateFileMissing
8
9from .templates import TemplateView
10
11__all__ = ["ErrorView"]
12
13
14class ErrorView(TemplateView):
15 status_code: int
16
17 def __init__(
18 self,
19 *,
20 request: Request,
21 status_code: int | None = None,
22 exception: Any | None = None,
23 ) -> None:
24 super().__init__(request=request)
25 self.status_code = status_code or self.status_code
26 self.exception = exception
27
28 def get_template_context(self) -> dict:
29 context = super().get_template_context()
30 context["status_code"] = self.status_code
31 context["exception"] = self.exception
32 return context
33
34 def get_template_names(self) -> list[str]:
35 # Try specific status code template (e.g. "404.html")
36 return [f"{self.status_code}.html"]
37
38 def get_request_handler(self) -> Callable[[], Any]:
39 return self.get # All methods (post, patch, etc.) will use the get()
40
41 def get_response(self) -> ResponseBase:
42 response = super().get_response()
43 # Set the status code we want
44 response.status_code = self.status_code
45 return response
46
47 def get(self) -> ResponseBase | int:
48 try:
49 return super().get()
50 except TemplateFileMissing:
51 return self.status_code