Skip to content

Commit 6c5dc90

Browse files
committed
Auto merge of #4119 - Turbo87:render-readme-errors, r=JohnTitor
admin::render_readmes: Use `Result` return types ... instead of dropping the errors via `Option` and using `panic!()` everywhere. /cc `@nipunn1313`
2 parents b13a645 + 49334b7 commit 6c5dc90

File tree

2 files changed

+47
-60
lines changed

2 files changed

+47
-60
lines changed

src/admin/render_readmes.rs

Lines changed: 46 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
schema::{crates, readme_renderings, versions},
55
uploaders::Uploader,
66
};
7+
use anyhow::{anyhow, Context};
78
use std::{io::Read, path::Path, sync::Arc, thread};
89

910
use cargo_registry_markdown::text_to_html;
@@ -37,7 +38,7 @@ pub struct Opts {
3738
crate_name: Option<String>,
3839
}
3940

40-
pub fn run(opts: Opts) {
41+
pub fn run(opts: Opts) -> anyhow::Result<()> {
4142
let base_config = Arc::new(config::Base::from_environment());
4243
let conn = db::connect_now().unwrap();
4344

@@ -102,21 +103,14 @@ pub fn run(opts: Opts) {
102103

103104
let mut tasks = Vec::with_capacity(page_size as usize);
104105
for (version, krate_name) in versions {
105-
Version::record_readme_rendering(version.id, &conn).unwrap_or_else(|_| {
106-
panic!(
107-
"[{}-{}] Couldn't record rendering time",
108-
krate_name, version.num
109-
)
110-
});
106+
Version::record_readme_rendering(version.id, &conn)
107+
.context("Couldn't record rendering time")?;
108+
111109
let client = client.clone();
112110
let base_config = base_config.clone();
113-
let handle = thread::spawn(move || {
111+
let handle = thread::spawn::<_, anyhow::Result<()>>(move || {
114112
println!("[{}-{}] Rendering README...", krate_name, version.num);
115-
let readme = get_readme(base_config.uploader(), &client, &version, &krate_name);
116-
if readme.is_none() {
117-
return;
118-
}
119-
let readme = readme.unwrap();
113+
let readme = get_readme(base_config.uploader(), &client, &version, &krate_name)?;
120114
let content_length = readme.len() as u64;
121115
let content = std::io::Cursor::new(readme);
122116
let readme_path = format!("readmes/{0}/{0}-{1}.html", krate_name, version.num);
@@ -125,6 +119,7 @@ pub fn run(opts: Opts) {
125119
header::CACHE_CONTROL,
126120
header::HeaderValue::from_static(CACHE_CONTROL_README),
127121
);
122+
128123
base_config
129124
.uploader()
130125
.upload(
@@ -135,21 +130,22 @@ pub fn run(opts: Opts) {
135130
"text/html",
136131
extra_headers,
137132
)
138-
.unwrap_or_else(|_| {
139-
panic!(
140-
"[{}-{}] Couldn't upload file to S3",
141-
krate_name, version.num
142-
)
143-
});
133+
.context("Failed to upload rendered README file to S3")?;
134+
135+
Ok(())
144136
});
145137
tasks.push(handle);
146138
}
147139
for handle in tasks {
148-
if let Err(err) = handle.join() {
149-
println!("Thread panicked: {:?}", err);
140+
match handle.join() {
141+
Err(err) => println!("Thread panicked: {:?}", err),
142+
Ok(Err(err)) => println!("Thread failed: {:?}", err),
143+
_ => {}
150144
}
151145
}
152146
}
147+
148+
Ok(())
153149
}
154150

155151
/// Renders the readme of an uploaded crate version.
@@ -158,7 +154,7 @@ fn get_readme(
158154
client: &Client,
159155
version: &Version,
160156
krate_name: &str,
161-
) -> Option<String> {
157+
) -> anyhow::Result<String> {
162158
let pkg_name = format!("{}-{}", krate_name, version.num);
163159

164160
let location = uploader.crate_location(krate_name, &version.num.to_string());
@@ -173,39 +169,30 @@ fn get_readme(
173169
header::USER_AGENT,
174170
header::HeaderValue::from_static(USER_AGENT),
175171
);
176-
let response = match client.get(&location).headers(extra_headers).send() {
177-
Ok(r) => r,
178-
Err(err) => {
179-
println!("[{}] Unable to fetch crate: {}", pkg_name, err);
180-
return None;
181-
}
182-
};
172+
let request = client.get(&location).headers(extra_headers);
173+
let response = request.send().context("Failed to fetch crate")?;
183174

184175
if !response.status().is_success() {
185-
println!(
186-
"[{}] Failed to get a 200 response: {}",
187-
pkg_name,
176+
return Err(anyhow!(
177+
"Failed to get a 200 response: {}",
188178
response.text().unwrap()
189-
);
190-
return None;
179+
));
191180
}
192181

193182
let reader = GzDecoder::new(response);
194183
let archive = Archive::new(reader);
195184
render_pkg_readme(archive, &pkg_name)
196185
}
197186

198-
fn render_pkg_readme<R: Read>(mut archive: Archive<R>, pkg_name: &str) -> Option<String> {
199-
let mut entries = archive
200-
.entries()
201-
.unwrap_or_else(|_| panic!("[{}] Invalid tar archive entries", pkg_name));
187+
fn render_pkg_readme<R: Read>(mut archive: Archive<R>, pkg_name: &str) -> anyhow::Result<String> {
188+
let mut entries = archive.entries().context("Invalid tar archive entries")?;
202189

203190
let manifest: Manifest = {
204191
let path = format!("{}/Cargo.toml", pkg_name);
205-
let contents = find_file_by_path(&mut entries, Path::new(&path), pkg_name)
206-
.unwrap_or_else(|| panic!("[{}] couldn't open file: Cargo.toml", pkg_name));
207-
toml::from_str(&contents)
208-
.unwrap_or_else(|_| panic!("[{}] Syntax error in manifest file", pkg_name))
192+
let contents = find_file_by_path(&mut entries, Path::new(&path))
193+
.context("Failed to read Cargo.toml file")?;
194+
195+
toml::from_str(&contents).context("Failed to parse manifest file")?
209196
};
210197

211198
let rendered = {
@@ -215,14 +202,16 @@ fn render_pkg_readme<R: Read>(mut archive: Archive<R>, pkg_name: &str) -> Option
215202
.clone()
216203
.unwrap_or_else(|| "README.md".into());
217204
let path = format!("{}/{}", pkg_name, readme_path);
218-
let contents = find_file_by_path(&mut entries, Path::new(&path), pkg_name)?;
205+
let contents = find_file_by_path(&mut entries, Path::new(&path))
206+
.with_context(|| format!("Failed to read {} file", readme_path))?;
207+
219208
text_to_html(
220209
&contents,
221210
&readme_path,
222211
manifest.package.repository.as_deref(),
223212
)
224213
};
225-
return Some(rendered);
214+
return Ok(rendered);
226215

227216
#[derive(Debug, Deserialize)]
228217
struct Package {
@@ -240,25 +229,20 @@ fn render_pkg_readme<R: Read>(mut archive: Archive<R>, pkg_name: &str) -> Option
240229
fn find_file_by_path<R: Read>(
241230
entries: &mut tar::Entries<'_, R>,
242231
path: &Path,
243-
pkg_name: &str,
244-
) -> Option<String> {
232+
) -> anyhow::Result<String> {
245233
let mut file = entries
246-
.find(|entry| match *entry {
234+
.filter_map(|entry| entry.ok())
235+
.find(|file| match file.path() {
236+
Ok(p) => p == path,
247237
Err(_) => false,
248-
Ok(ref file) => {
249-
let filepath = match file.path() {
250-
Ok(p) => p,
251-
Err(_) => return false,
252-
};
253-
filepath == path
254-
}
255-
})?
256-
.unwrap_or_else(|_| panic!("[{}] file is not present: {}", pkg_name, path.display()));
238+
})
239+
.ok_or_else(|| anyhow!("Failed to find tarball entry: {}", path.display()))?;
257240

258241
let mut contents = String::new();
259242
file.read_to_string(&mut contents)
260-
.unwrap_or_else(|_| panic!("[{}] Couldn't read file contents", pkg_name));
261-
Some(contents)
243+
.context("Failed to read file contents")?;
244+
245+
Ok(contents)
262246
}
263247

264248
#[cfg(test)]
@@ -304,7 +288,10 @@ readme = "README.md"
304288
"#,
305289
);
306290
let serialized_archive = pkg.into_inner().unwrap();
307-
assert!(render_pkg_readme(tar::Archive::new(&*serialized_archive), "foo-0.0.1").is_none());
291+
assert_err!(render_pkg_readme(
292+
tar::Archive::new(&*serialized_archive),
293+
"foo-0.0.1"
294+
));
308295
}
309296

310297
#[test]

src/bin/crates-admin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn main() -> anyhow::Result<()> {
3333
SubCommand::DeleteCrate(opts) => delete_crate::run(opts),
3434
SubCommand::DeleteVersion(opts) => delete_version::run(opts),
3535
SubCommand::Populate(opts) => populate::run(opts),
36-
SubCommand::RenderReadmes(opts) => render_readmes::run(opts),
36+
SubCommand::RenderReadmes(opts) => render_readmes::run(opts)?,
3737
SubCommand::TestPagerduty(opts) => test_pagerduty::run(opts)?,
3838
SubCommand::TransferCrates(opts) => transfer_crates::run(opts),
3939
SubCommand::VerifyToken(opts) => verify_token::run(opts).unwrap(),

0 commit comments

Comments
 (0)