tangled
alpha
login
or
join now
ericwood.org
/
photos-site
1
fork
atom
A little app to serve my photography from my personal website
1
fork
atom
overview
issues
pulls
pipelines
improved error presentation
ericwood.org
2 months ago
7f1ba615
eb3e53b5
0/0
Waiting for spindle ...
+71
-4
4 changed files
expand all
collapse all
unified
split
Cargo.lock
Cargo.toml
src
app_error.rs
templates.rs
+16
Cargo.lock
reviewed
···
2201
2201
]
2202
2202
2203
2203
[[package]]
2204
2204
+
name = "html-escape"
2205
2205
+
version = "0.2.13"
2206
2206
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2207
2207
+
checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476"
2208
2208
+
dependencies = [
2209
2209
+
"utf8-width",
2210
2210
+
]
2211
2211
+
2212
2212
+
[[package]]
2204
2213
name = "http"
2205
2214
version = "1.3.1"
2206
2215
source = "registry+https://github.com/rust-lang/crates.io-index"
···
3063
3072
"chrono",
3064
3073
"comrak",
3065
3074
"dotenvy",
3075
3075
+
"html-escape",
3066
3076
"init-tracing-opentelemetry",
3067
3077
"minijinja",
3068
3078
"minijinja-autoreload",
···
4627
4637
version = "2.1.3"
4628
4638
source = "registry+https://github.com/rust-lang/crates.io-index"
4629
4639
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
4640
4640
+
4641
4641
+
[[package]]
4642
4642
+
name = "utf8-width"
4643
4643
+
version = "0.1.8"
4644
4644
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4645
4645
+
checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091"
4630
4646
4631
4647
[[package]]
4632
4648
name = "utf8_iter"
+2
-1
Cargo.toml
reviewed
···
15
15
"tracing_subscriber_ext",
16
16
"metrics",
17
17
] }
18
18
-
minijinja = { version = "2.12.0", features = ["loader"] }
18
18
+
minijinja = { version = "2.12.0", features = ["loader", "debug"] }
19
19
minijinja-autoreload = "2.12.0"
20
20
serde = "1.0.228"
21
21
serde_html_form = "0.2.8"
···
32
32
arborium = { version = "2.3.2", features = ["all-languages"] }
33
33
slug = "0.1.6"
34
34
regex = "1.12.2"
35
35
+
html-escape = "0.2.13"
+45
-1
src/app_error.rs
reviewed
···
45
45
let body = if status_code == StatusCode::INTERNAL_SERVER_ERROR && !is_dev {
46
46
"internal server error".to_string()
47
47
} else {
48
48
-
self.to_string()
48
48
+
let body = if let Self::Anyhow(e) = &self
49
49
+
&& let Some(template_error) = e.downcast_ref::<minijinja::Error>()
50
50
+
{
51
51
+
let debug = template_error.display_debug_info().to_string();
52
52
+
let kind = template_error.kind();
53
53
+
let detail = template_error.detail().unwrap_or_default();
54
54
+
let name = template_error.name().unwrap_or_default();
55
55
+
let line = template_error.line().unwrap_or_default();
56
56
+
57
57
+
format!("{kind}: {detail}\n{name}:{line}\n{}", debug)
58
58
+
} else {
59
59
+
format!("{:#?}", self)
60
60
+
};
61
61
+
62
62
+
render_error(body)
49
63
};
50
64
51
65
(self.status_code(), Html(body)).into_response()
52
66
}
53
67
}
68
68
+
69
69
+
fn render_error(body: String) -> String {
70
70
+
let style = r#"
71
71
+
body {
72
72
+
padding: 30px;
73
73
+
font-family: sans-serif;
74
74
+
}
75
75
+
76
76
+
pre {
77
77
+
background-color: #eee;
78
78
+
padding: 20px;
79
79
+
border-radius: 6px;
80
80
+
}
81
81
+
"#;
82
82
+
83
83
+
format!(
84
84
+
r#"
85
85
+
<html>
86
86
+
<head>
87
87
+
<style type="text/css">{style}</style>
88
88
+
</head>
89
89
+
<body>
90
90
+
<h1>Error:</h1>
91
91
+
<pre><code>{}</code></pre>
92
92
+
</body>
93
93
+
</html>
94
94
+
"#,
95
95
+
html_escape::encode_text(&body)
96
96
+
)
97
97
+
}
+8
-2
src/templates.rs
reviewed
···
15
15
pub fn load_templates_dyn(config: &Config) -> AutoReloader {
16
16
let should_autoreload = config.auto_reload_templates;
17
17
let blog_posts_path_str = config.blog_posts_path.clone();
18
18
+
let is_prod = config.is_prod();
18
19
19
20
AutoReloader::new(move |notifier| {
20
21
let mut env = Environment::new();
21
22
env.set_loader(loader);
23
23
+
env.set_debug(!is_prod);
22
24
23
25
notifier.set_fast_reload(true);
24
26
···
92
94
Ok(Some(template))
93
95
}
94
96
95
95
-
pub fn render<S>(reloader: &AutoReloader, name: &str, context: S) -> anyhow::Result<String>
97
97
+
pub fn render<S>(
98
98
+
reloader: &AutoReloader,
99
99
+
name: &str,
100
100
+
context: S,
101
101
+
) -> Result<String, minijinja::Error>
96
102
where
97
103
S: Serialize,
98
104
{
99
105
let template_env = reloader.acquire_env()?;
100
106
let template = template_env.get_template(name)?;
101
101
-
Ok(template.render(context)?)
107
107
+
template.render(context)
102
108
}
103
109
104
110
fn url_escape(input: String) -> String {