Plain is headed towards 1.0! Subscribe for development updates →

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