Skip to content

Commit d5a1127

Browse files
KixironJoshua Nelson
authored and
Joshua Nelson
committed
Error, ctry! and cexpect!
1 parent 46254eb commit d5a1127

File tree

13 files changed

+231
-246
lines changed

13 files changed

+231
-246
lines changed

src/docbuilder/limits.rs

Lines changed: 1 addition & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::error::Result;
22
use postgres::Connection;
33
use serde::Serialize;
4-
use std::{collections::BTreeMap, time::Duration};
4+
use std::{time::Duration};
55

66
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
77
pub(crate) struct Limits {
@@ -67,52 +67,6 @@ impl Limits {
6767
pub(crate) fn targets(&self) -> usize {
6868
self.targets
6969
}
70-
71-
pub(crate) fn for_website(&self) -> BTreeMap<String, String> {
72-
let mut res = BTreeMap::new();
73-
res.insert("Available RAM".into(), SIZE_SCALE(self.memory));
74-
res.insert(
75-
"Maximum rustdoc execution time".into(),
76-
TIME_SCALE(self.timeout.as_secs() as usize),
77-
);
78-
res.insert(
79-
"Maximum size of a build log".into(),
80-
SIZE_SCALE(self.max_log_size),
81-
);
82-
if self.networking {
83-
res.insert("Network access".into(), "allowed".into());
84-
} else {
85-
res.insert("Network access".into(), "blocked".into());
86-
}
87-
res.insert(
88-
"Maximum number of build targets".into(),
89-
self.targets.to_string(),
90-
);
91-
res
92-
}
93-
}
94-
95-
const TIME_SCALE: fn(usize) -> String = |v| scale(v, 60, &["seconds", "minutes", "hours"]);
96-
const SIZE_SCALE: fn(usize) -> String = |v| scale(v, 1024, &["bytes", "KB", "MB", "GB"]);
97-
98-
fn scale(value: usize, interval: usize, labels: &[&str]) -> String {
99-
let (mut value, interval) = (value as f64, interval as f64);
100-
let mut chosen_label = &labels[0];
101-
for label in &labels[1..] {
102-
if value / interval >= 1.0 {
103-
chosen_label = label;
104-
value /= interval;
105-
} else {
106-
break;
107-
}
108-
}
109-
// 2.x
110-
let mut value = format!("{:.1}", value);
111-
// 2.0 -> 2
112-
if value.ends_with(".0") {
113-
value.truncate(value.len() - 2);
114-
}
115-
format!("{} {}", value, chosen_label)
11670
}
11771

11872
#[cfg(test)]
@@ -161,56 +115,4 @@ mod test {
161115
Ok(())
162116
});
163117
}
164-
165-
#[test]
166-
fn display_limits() {
167-
let limits = Limits {
168-
memory: 102_400,
169-
timeout: Duration::from_secs(300),
170-
targets: 1,
171-
..Limits::default()
172-
};
173-
let display = limits.for_website();
174-
assert_eq!(display.get("Network access"), Some(&"blocked".into()));
175-
assert_eq!(
176-
display.get("Maximum size of a build log"),
177-
Some(&"100 KB".into())
178-
);
179-
assert_eq!(
180-
display.get("Maximum number of build targets"),
181-
Some(&limits.targets.to_string())
182-
);
183-
assert_eq!(
184-
display.get("Maximum rustdoc execution time"),
185-
Some(&"5 minutes".into())
186-
);
187-
assert_eq!(display.get("Available RAM"), Some(&"100 KB".into()));
188-
}
189-
190-
#[test]
191-
fn scale_limits() {
192-
// time
193-
assert_eq!(TIME_SCALE(300), "5 minutes");
194-
assert_eq!(TIME_SCALE(1), "1 seconds");
195-
assert_eq!(TIME_SCALE(7200), "2 hours");
196-
197-
// size
198-
assert_eq!(SIZE_SCALE(1), "1 bytes");
199-
assert_eq!(SIZE_SCALE(100), "100 bytes");
200-
assert_eq!(SIZE_SCALE(1024), "1 KB");
201-
assert_eq!(SIZE_SCALE(10240), "10 KB");
202-
assert_eq!(SIZE_SCALE(1_048_576), "1 MB");
203-
assert_eq!(SIZE_SCALE(10_485_760), "10 MB");
204-
assert_eq!(SIZE_SCALE(1_073_741_824), "1 GB");
205-
assert_eq!(SIZE_SCALE(10_737_418_240), "10 GB");
206-
assert_eq!(SIZE_SCALE(std::u32::MAX as usize), "4 GB");
207-
208-
// fractional sizes
209-
assert_eq!(TIME_SCALE(90), "1.5 minutes");
210-
assert_eq!(TIME_SCALE(5400), "1.5 hours");
211-
212-
assert_eq!(SIZE_SCALE(1_288_490_189), "1.2 GB");
213-
assert_eq!(SIZE_SCALE(3_758_096_384), "3.5 GB");
214-
assert_eq!(SIZE_SCALE(1_048_051_712), "999.5 MB");
215-
}
216118
}

src/web/builds.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,17 @@ impl_webpage! {
3838

3939
pub fn build_list_handler(req: &mut Request) -> IronResult<Response> {
4040
let router = extension!(req, Router);
41-
let name = cexpect!(router.find("name"));
42-
let version = cexpect!(router.find("version"));
41+
let name = cexpect!(req, router.find("name"));
42+
let version = cexpect!(req, router.find("version"));
4343
let req_build_id: i32 = router.find("id").unwrap_or("0").parse().unwrap_or(0);
4444

4545
let conn = extension!(req, Pool).get()?;
46-
let limits = ctry!(Limits::for_crate(&conn, name));
46+
let limits = ctry!(req, Limits::for_crate(&conn, name));
4747

48-
let query = ctry!(conn.query(
49-
"SELECT crates.name,
48+
let query = ctry!(
49+
req,
50+
conn.query(
51+
"SELECT crates.name,
5052
releases.version,
5153
releases.description,
5254
releases.rustdoc_status,
@@ -62,8 +64,9 @@ pub fn build_list_handler(req: &mut Request) -> IronResult<Response> {
6264
INNER JOIN crates ON releases.crate_id = crates.id
6365
WHERE crates.name = $1 AND releases.version = $2
6466
ORDER BY id DESC",
65-
&[&name, &version]
66-
));
67+
&[&name, &version]
68+
)
69+
);
6770

6871
let mut build_log = None;
6972
// FIXME: getting builds.output may cause performance issues when release have tons of builds

src/web/crate_details.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ fn map_to_release(conn: &Connection, crate_id: i32, version: String) -> Release
356356
pub fn crate_details_handler(req: &mut Request) -> IronResult<Response> {
357357
let router = extension!(req, Router);
358358
// this handler must always called with a crate name
359-
let name = cexpect!(router.find("name"));
359+
let name = cexpect!(req, router.find("name"));
360360
let req_version = router.find("version");
361361

362362
let conn = extension!(req, Pool).get()?;
@@ -372,9 +372,15 @@ pub fn crate_details_handler(req: &mut Request) -> IronResult<Response> {
372372
.to_resp("crate_details")
373373
}
374374
Some(MatchSemver::Semver((version, _))) => {
375-
let url = ctry!(Url::parse(
376-
&format!("{}/crate/{}/{}", redirect_base(req), name, version)[..]
377-
));
375+
let url = ctry!(
376+
req,
377+
Url::parse(&format!(
378+
"{}/crate/{}/{}",
379+
redirect_base(req),
380+
name,
381+
version
382+
)),
383+
);
378384

379385
Ok(super::redirect(url))
380386
}

src/web/error.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
use crate::{
22
db::PoolError,
3-
web::{
4-
page::{Page, WebPage},
5-
releases::Search,
6-
},
3+
web::{page::WebPage, releases::Search, ErrorPage},
74
};
85
use failure::Fail;
9-
use iron::{status, Handler, IronError, IronResult, Plugin, Request, Response};
6+
use iron::{status::Status, Handler, IronError, IronResult, Plugin, Request, Response};
107
use params::{Params, Value};
118
use std::{error::Error, fmt};
129

@@ -36,18 +33,24 @@ impl Handler for Nope {
3633
match *self {
3734
Nope::ResourceNotFound => {
3835
// user tried to navigate to a resource (doc page/file) that doesn't exist
39-
Page::new("no such resource".to_owned())
40-
.set_status(status::NotFound)
41-
.title("The requested resource does not exist")
42-
.to_resp("error")
36+
// TODO: Display the attempted page
37+
ErrorPage {
38+
title: "The requested resource does not exist".into(),
39+
message: Some("no such resource".into()),
40+
status: Status::NotFound,
41+
}
42+
.into_response(req)
4343
}
4444

4545
Nope::CrateNotFound => {
4646
// user tried to navigate to a crate that doesn't exist
47-
Page::new("no such crate".to_owned())
48-
.set_status(status::NotFound)
49-
.title("The requested crate does not exist")
50-
.to_resp("error")
47+
// TODO: Display the attempted crate and a link to a search for said crate
48+
ErrorPage {
49+
title: "The requested crate does not exist".into(),
50+
message: Some("no such crate".into()),
51+
status: Status::NotFound,
52+
}
53+
.into_response(req)
5154
}
5255

5356
Nope::NoResults => {
@@ -58,15 +61,15 @@ impl Handler for Nope {
5861
Search {
5962
title: format!("No crates found matching '{}'", query),
6063
search_query: Some(query.to_owned()),
61-
status: status::NotFound,
64+
status: Status::NotFound,
6265
..Default::default()
6366
}
6467
.into_response(req)
6568
} else {
6669
// user did a search with no search terms
6770
Search {
6871
title: "No results given for empty search query".to_owned(),
69-
status: status::NotFound,
72+
status: Status::NotFound,
7073
..Default::default()
7174
}
7275
.into_response(req)
@@ -75,17 +78,19 @@ impl Handler for Nope {
7578

7679
Nope::InternalServerError => {
7780
// something went wrong, details should have been logged
78-
Page::new("internal server error".to_owned())
79-
.set_status(status::InternalServerError)
80-
.title("Internal server error")
81-
.to_resp("error")
81+
ErrorPage {
82+
title: "Internal server error".into(),
83+
message: Some("internal server error".into()),
84+
status: Status::InternalServerError,
85+
}
86+
.into_response(req)
8287
}
8388
}
8489
}
8590
}
8691

8792
impl From<PoolError> for IronError {
8893
fn from(err: PoolError) -> IronError {
89-
IronError::new(err.compat(), status::InternalServerError)
94+
IronError::new(err.compat(), Status::InternalServerError)
9095
}
9196
}

src/web/metrics.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ pub fn metrics_handler(req: &mut Request) -> IronResult<Response> {
154154
USED_DB_CONNECTIONS.set(pool.used_connections() as i64);
155155
IDLE_DB_CONNECTIONS.set(pool.idle_connections() as i64);
156156

157-
QUEUED_CRATES_COUNT.set(ctry!(queue.pending_count()) as i64);
158-
PRIORITIZED_CRATES_COUNT.set(ctry!(queue.prioritized_count()) as i64);
159-
FAILED_CRATES_COUNT.set(ctry!(queue.failed_count()) as i64);
157+
QUEUED_CRATES_COUNT.set(ctry!(req, queue.pending_count()) as i64);
158+
PRIORITIZED_CRATES_COUNT.set(ctry!(req, queue.prioritized_count()) as i64);
159+
FAILED_CRATES_COUNT.set(ctry!(req, queue.failed_count()) as i64);
160160

161161
#[cfg(target_os = "linux")]
162162
{
@@ -169,12 +169,12 @@ pub fn metrics_handler(req: &mut Request) -> IronResult<Response> {
169169

170170
let mut buffer = Vec::new();
171171
let families = prometheus::gather();
172-
ctry!(TextEncoder::new().encode(&families, &mut buffer));
172+
ctry!(req, TextEncoder::new().encode(&families, &mut buffer));
173173

174174
let mut resp = Response::with(buffer);
175175
resp.status = Some(Status::Ok);
176-
resp.headers
177-
.set(ContentType("text/plain; version=0.0.4".parse().unwrap()));
176+
resp.headers.set(ContentType::plaintext());
177+
178178
Ok(resp)
179179
}
180180

0 commit comments

Comments
 (0)