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