@@ -210,7 +210,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
210
210
// `b`, and we uploaded `a` and `b` but only confirmed `a`, then on
211
211
// the following pass through the outer loop nothing will be ready for
212
212
// upload.
213
- for pkg_id in plan. take_ready ( ) {
213
+ for pkg_id in plan. take_ready ( ) . into_iter ( ) {
214
214
let ( pkg, ( _features, tarball) ) = & pkg_dep_graph. packages [ & pkg_id] ;
215
215
opts. gctx . shell ( ) . status ( "Uploading" , pkg. package_id ( ) ) ?;
216
216
@@ -236,15 +236,52 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
236
236
) ?) ) ;
237
237
}
238
238
239
- transmit (
239
+ // Always wrap transmit with context for enhanced error reporting
240
+ let transmit_result = transmit (
240
241
opts. gctx ,
241
242
ws,
242
243
pkg,
243
244
tarball. file ( ) ,
244
245
& mut registry,
245
246
source_ids. original ,
246
247
opts. dry_run ,
247
- ) ?;
248
+ ) . map_err ( |e| {
249
+ // Collect remaining packages that have not been published yet
250
+ let mut remaining: Vec < _ > = plan
251
+ . iter ( )
252
+ . filter ( |id| * id != pkg_id)
253
+ . map ( |id| {
254
+ let pkg = & pkg_dep_graph. packages [ & id] . 0 ;
255
+ format ! ( "{} v{}" , pkg. name( ) , pkg. version( ) )
256
+ } )
257
+ . collect ( ) ;
258
+ // Also include any packages that are still waiting for confirmation
259
+ for id in to_confirm. iter ( ) . filter ( |id| * * id != pkg_id) {
260
+ let pkg = & pkg_dep_graph. packages [ & id] . 0 ;
261
+ let entry = format ! ( "{} v{}" , pkg. name( ) , pkg. version( ) ) ;
262
+ if !remaining. contains ( & entry) {
263
+ remaining. push ( entry) ;
264
+ }
265
+ }
266
+
267
+ let message = if !remaining. is_empty ( ) {
268
+ format ! (
269
+ "failed to publish `{}` v{}; the following crates have not been published yet: {}" ,
270
+ pkg. name( ) ,
271
+ pkg. version( ) ,
272
+ remaining. join( ", " )
273
+ )
274
+ } else {
275
+ format ! ( "failed to publish `{}` v{}" , pkg. name( ) , pkg. version( ) )
276
+ } ;
277
+
278
+ e. context ( message)
279
+ } ) ;
280
+
281
+ if let Err ( e) = transmit_result {
282
+ return Err ( e) ;
283
+ }
284
+
248
285
to_confirm. insert ( pkg_id) ;
249
286
250
287
if !opts. dry_run {
@@ -450,12 +487,13 @@ fn verify_unpublished(
450
487
source. describe( )
451
488
) ) ?;
452
489
} else {
453
- bail ! (
490
+ // Return error instead of bail! so it can be wrapped with enhanced context
491
+ return Err ( anyhow:: anyhow!(
454
492
"crate {}@{} already exists on {}" ,
455
493
pkg. name( ) ,
456
494
pkg. version( ) ,
457
495
source. describe( )
458
- ) ;
496
+ ) ) ;
459
497
}
460
498
}
461
499
0 commit comments