Skip to content

Commit ccf781a

Browse files
committed
Auto merge of #9213 - ehuss:registry-api-errors, r=alexcrichton
Minor update to registry API error messages. This is a minor update to the registry API errors, trying to make them a little clearer and more helpful. My concerns were: * `api errors (status 200 OK): some error message` — why was there both an error and 200 OK? * `api errors` — What is an "api error" anyways? The user is probably not familiar with the "registry API". * Adds the URL of the server it is actually talking to, in case you may be confused when using a registry other than crates.io. This also tries to make it clearer that the message is coming from the remote server, and not cargo itself.
2 parents 0b2059e + c9bd6e1 commit ccf781a

File tree

5 files changed

+170
-94
lines changed

5 files changed

+170
-94
lines changed

crates/crates-io/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,13 @@ impl fmt::Display for ResponseError {
155155
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156156
match self {
157157
ResponseError::Curl(e) => write!(f, "{}", e),
158-
ResponseError::Api { code, errors } => write!(
159-
f,
160-
"api errors (status {} {}): {}",
161-
code,
162-
reason(*code),
163-
errors.join(", ")
164-
),
158+
ResponseError::Api { code, errors } => {
159+
f.write_str("the remote server responded with an error")?;
160+
if *code != 200 {
161+
write!(f, " (status {} {})", code, reason(*code))?;
162+
};
163+
write!(f, ": {}", errors.join(", "))
164+
}
165165
ResponseError::Code {
166166
code,
167167
headers,

src/cargo/ops/registry.rs

Lines changed: 89 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -286,65 +286,62 @@ fn transmit(
286286
None => BTreeMap::new(),
287287
};
288288

289-
let publish = registry.publish(
290-
&NewCrate {
291-
name: pkg.name().to_string(),
292-
vers: pkg.version().to_string(),
293-
deps,
294-
features: string_features,
295-
authors: authors.clone(),
296-
description: description.clone(),
297-
homepage: homepage.clone(),
298-
documentation: documentation.clone(),
299-
keywords: keywords.clone(),
300-
categories: categories.clone(),
301-
readme: readme_content,
302-
readme_file: readme.clone(),
303-
repository: repository.clone(),
304-
license: license.clone(),
305-
license_file: license_file.clone(),
306-
badges: badges.clone(),
307-
links: links.clone(),
308-
v: None,
309-
},
310-
tarball,
311-
);
312-
313-
match publish {
314-
Ok(warnings) => {
315-
if !warnings.invalid_categories.is_empty() {
316-
let msg = format!(
317-
"the following are not valid category slugs and were \
318-
ignored: {}. Please see https://crates.io/category_slugs \
319-
for the list of all category slugs. \
320-
",
321-
warnings.invalid_categories.join(", ")
322-
);
323-
config.shell().warn(&msg)?;
324-
}
325-
326-
if !warnings.invalid_badges.is_empty() {
327-
let msg = format!(
328-
"the following are not valid badges and were ignored: {}. \
329-
Either the badge type specified is unknown or a required \
330-
attribute is missing. Please see \
331-
https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata \
332-
for valid badge types and their required attributes.",
333-
warnings.invalid_badges.join(", ")
334-
);
335-
config.shell().warn(&msg)?;
336-
}
289+
let warnings = registry
290+
.publish(
291+
&NewCrate {
292+
name: pkg.name().to_string(),
293+
vers: pkg.version().to_string(),
294+
deps,
295+
features: string_features,
296+
authors: authors.clone(),
297+
description: description.clone(),
298+
homepage: homepage.clone(),
299+
documentation: documentation.clone(),
300+
keywords: keywords.clone(),
301+
categories: categories.clone(),
302+
readme: readme_content,
303+
readme_file: readme.clone(),
304+
repository: repository.clone(),
305+
license: license.clone(),
306+
license_file: license_file.clone(),
307+
badges: badges.clone(),
308+
links: links.clone(),
309+
v: None,
310+
},
311+
tarball,
312+
)
313+
.chain_err(|| format!("failed to publish to registry at {}", registry.host()))?;
314+
315+
if !warnings.invalid_categories.is_empty() {
316+
let msg = format!(
317+
"the following are not valid category slugs and were \
318+
ignored: {}. Please see https://crates.io/category_slugs \
319+
for the list of all category slugs. \
320+
",
321+
warnings.invalid_categories.join(", ")
322+
);
323+
config.shell().warn(&msg)?;
324+
}
337325

338-
if !warnings.other.is_empty() {
339-
for msg in warnings.other {
340-
config.shell().warn(&msg)?;
341-
}
342-
}
326+
if !warnings.invalid_badges.is_empty() {
327+
let msg = format!(
328+
"the following are not valid badges and were ignored: {}. \
329+
Either the badge type specified is unknown or a required \
330+
attribute is missing. Please see \
331+
https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata \
332+
for valid badge types and their required attributes.",
333+
warnings.invalid_badges.join(", ")
334+
);
335+
config.shell().warn(&msg)?;
336+
}
343337

344-
Ok(())
338+
if !warnings.other.is_empty() {
339+
for msg in warnings.other {
340+
config.shell().warn(&msg)?;
345341
}
346-
Err(e) => Err(e),
347342
}
343+
344+
Ok(())
348345
}
349346

350347
/// Returns the index and token from the config file for the given registry.
@@ -731,9 +728,9 @@ pub fn registry_login(
731728
input
732729
.lock()
733730
.read_line(&mut line)
734-
.chain_err(|| "failed to read stdin")
735-
.map_err(anyhow::Error::from)?;
736-
// Automatically remove `cargo login` from an inputted token to allow direct pastes from `registry.host()`/me.
731+
.chain_err(|| "failed to read stdin")?;
732+
// Automatically remove `cargo login` from an inputted token to
733+
// allow direct pastes from `registry.host()`/me.
737734
line.replace("cargo login", "").trim().to_string()
738735
}
739736
};
@@ -820,9 +817,13 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
820817

821818
if let Some(ref v) = opts.to_add {
822819
let v = v.iter().map(|s| &s[..]).collect::<Vec<_>>();
823-
let msg = registry
824-
.add_owners(&name, &v)
825-
.map_err(|e| format_err!("failed to invite owners to crate {}: {}", name, e))?;
820+
let msg = registry.add_owners(&name, &v).chain_err(|| {
821+
format!(
822+
"failed to invite owners to crate `{}` on registry at {}",
823+
name,
824+
registry.host()
825+
)
826+
})?;
826827

827828
config.shell().status("Owner", msg)?;
828829
}
@@ -832,15 +833,23 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
832833
config
833834
.shell()
834835
.status("Owner", format!("removing {:?} from crate {}", v, name))?;
835-
registry
836-
.remove_owners(&name, &v)
837-
.chain_err(|| format!("failed to remove owners from crate {}", name))?;
836+
registry.remove_owners(&name, &v).chain_err(|| {
837+
format!(
838+
"failed to remove owners from crate `{}` on registry at {}",
839+
name,
840+
registry.host()
841+
)
842+
})?;
838843
}
839844

840845
if opts.list {
841-
let owners = registry
842-
.list_owners(&name)
843-
.chain_err(|| format!("failed to list owners of crate {}", name))?;
846+
let owners = registry.list_owners(&name).chain_err(|| {
847+
format!(
848+
"failed to list owners of crate `{}` on registry at {}",
849+
name,
850+
registry.host()
851+
)
852+
})?;
844853
for owner in owners.iter() {
845854
drop_print!(config, "{}", owner.login);
846855
match (owner.name.as_ref(), owner.email.as_ref()) {
@@ -882,16 +891,19 @@ pub fn yank(
882891
config
883892
.shell()
884893
.status("Unyank", format!("{}:{}", name, version))?;
885-
registry
886-
.unyank(&name, &version)
887-
.chain_err(|| "failed to undo a yank")?;
894+
registry.unyank(&name, &version).chain_err(|| {
895+
format!(
896+
"failed to undo a yank from the registry at {}",
897+
registry.host()
898+
)
899+
})?;
888900
} else {
889901
config
890902
.shell()
891903
.status("Yank", format!("{}:{}", name, version))?;
892904
registry
893905
.yank(&name, &version)
894-
.chain_err(|| "failed to yank")?;
906+
.chain_err(|| format!("failed to yank from the registry at {}", registry.host()))?;
895907
}
896908

897909
Ok(())
@@ -937,9 +949,12 @@ pub fn search(
937949
}
938950

939951
let (mut registry, _, source_id) = registry(config, None, index, reg, false, false)?;
940-
let (crates, total_crates) = registry
941-
.search(query, limit)
942-
.chain_err(|| "failed to retrieve search results from the registry")?;
952+
let (crates, total_crates) = registry.search(query, limit).chain_err(|| {
953+
format!(
954+
"failed to retrieve search results from the registry at {}",
955+
registry.host()
956+
)
957+
})?;
943958

944959
let names = crates
945960
.iter()

tests/testsuite/owner.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ fn simple_add() {
8181
.with_status(101)
8282
.with_stderr(
8383
" Updating `[..]` index
84-
error: failed to invite owners to crate foo: EOF while parsing a value at line 1 column 0",
84+
error: failed to invite owners to crate `foo` on registry at file://[..]
85+
86+
Caused by:
87+
EOF while parsing a value at line 1 column 0",
8588
)
8689
.run();
8790
}
@@ -111,7 +114,7 @@ fn simple_remove() {
111114
.with_stderr(
112115
" Updating `[..]` index
113116
Owner removing [\"username\"] from crate foo
114-
error: failed to remove owners from crate foo
117+
error: failed to remove owners from crate `foo` on registry at file://[..]
115118
116119
Caused by:
117120
EOF while parsing a value at line 1 column 0",

tests/testsuite/publish.rs

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,56 @@ fn api_error_json() {
14901490
[UPDATING] [..]
14911491
[PACKAGING] foo v0.0.1 [..]
14921492
[UPLOADING] foo v0.0.1 [..]
1493-
[ERROR] api errors (status 403 Forbidden): you must be logged in
1493+
[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1494+
1495+
Caused by:
1496+
the remote server responded with an error (status 403 Forbidden): you must be logged in
1497+
",
1498+
)
1499+
.run();
1500+
1501+
t.join().unwrap();
1502+
}
1503+
1504+
#[cargo_test]
1505+
fn api_error_200() {
1506+
// Registry returns an API error with a 200 status code.
1507+
let t = registry::RegistryBuilder::new().build_api_server(&|_headers| {
1508+
(
1509+
200,
1510+
&r#"{"errors": [{"detail": "max upload size is 123"}]}"#,
1511+
)
1512+
});
1513+
1514+
let p = project()
1515+
.file(
1516+
"Cargo.toml",
1517+
r#"
1518+
[project]
1519+
name = "foo"
1520+
version = "0.0.1"
1521+
authors = []
1522+
license = "MIT"
1523+
description = "foo"
1524+
documentation = "foo"
1525+
homepage = "foo"
1526+
repository = "foo"
1527+
"#,
1528+
)
1529+
.file("src/lib.rs", "")
1530+
.build();
1531+
1532+
p.cargo("publish --no-verify --registry alternative")
1533+
.with_status(101)
1534+
.with_stderr(
1535+
"\
1536+
[UPDATING] [..]
1537+
[PACKAGING] foo v0.0.1 [..]
1538+
[UPLOADING] foo v0.0.1 [..]
1539+
[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1540+
1541+
Caused by:
1542+
the remote server responded with an error: max upload size is 123
14941543
",
14951544
)
14961545
.run();
@@ -1528,13 +1577,16 @@ fn api_error_code() {
15281577
[UPDATING] [..]
15291578
[PACKAGING] foo v0.0.1 [..]
15301579
[UPLOADING] foo v0.0.1 [..]
1531-
[ERROR] failed to get a 200 OK response, got 400
1532-
headers:
1533-
<tab>HTTP/1.1 400
1534-
<tab>Content-Length: 7
1535-
<tab>
1536-
body:
1537-
go away
1580+
[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1581+
1582+
Caused by:
1583+
failed to get a 200 OK response, got 400
1584+
headers:
1585+
<tab>HTTP/1.1 400
1586+
<tab>Content-Length: 7
1587+
<tab>
1588+
body:
1589+
go away
15381590
",
15391591
)
15401592
.run();
@@ -1577,7 +1629,10 @@ fn api_curl_error() {
15771629
[UPDATING] [..]
15781630
[PACKAGING] foo v0.0.1 [..]
15791631
[UPLOADING] foo v0.0.1 [..]
1580-
[ERROR] [52] [..]
1632+
[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1633+
1634+
Caused by:
1635+
[52] [..]
15811636
",
15821637
)
15831638
.run();
@@ -1616,7 +1671,10 @@ fn api_other_error() {
16161671
[UPDATING] [..]
16171672
[PACKAGING] foo v0.0.1 [..]
16181673
[UPLOADING] foo v0.0.1 [..]
1619-
[ERROR] invalid response from server
1674+
[ERROR] failed to publish to registry at http://127.0.0.1:[..]/
1675+
1676+
Caused by:
1677+
invalid response from server
16201678
16211679
Caused by:
16221680
response body was not valid utf-8

tests/testsuite/yank.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn simple() {
3939
.with_stderr(
4040
" Updating `[..]` index
4141
Unyank foo:0.0.1
42-
error: failed to undo a yank
42+
error: failed to undo a yank from the registry at file:///[..]
4343
4444
Caused by:
4545
EOF while parsing a value at line 1 column 0",

0 commit comments

Comments
 (0)