From 46cf20a3f74923a79c4667f6f9becaec9305bc9f Mon Sep 17 00:00:00 2001
From: Jiahao XU <Jiahao_XU@outlook.com>
Date: Thu, 21 Jul 2022 20:40:31 +1000
Subject: [PATCH 1/4] Add new variant `BinstallError::TaskJoinError`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
---
 src/errors.rs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/errors.rs b/src/errors.rs
index 6be71942..f8451ee3 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -3,6 +3,7 @@ use std::process::{ExitCode, Termination};
 use log::{error, warn};
 use miette::{Diagnostic, Report};
 use thiserror::Error;
+use tokio::task;
 
 /// Errors emitted by the library portion of cargo-binstall.
 #[derive(Error, Diagnostic, Debug)]
@@ -185,6 +186,10 @@ pub enum BinstallError {
         help("Remove the `--manifest-path` or only specify one `$crate_name`")
     )]
     ManifestPathConflictedWithBatchInstallation,
+
+    #[error("Failed to join tokio::task::JoinHandle")]
+    #[diagnostic(severity(error), code(binstall::join_error))]
+    TaskJoinError(#[from] task::JoinError),
 }
 
 impl BinstallError {
@@ -213,6 +218,7 @@ impl BinstallError {
             VersionUnavailable { .. } => 83,
             DuplicateVersionReq => 84,
             ManifestPathConflictedWithBatchInstallation => 85,
+            TaskJoinError(_) => 17,
         };
 
         // reserved codes

From 6e5ecc46cf1280a381f4f690feda5e9f09e208e3 Mon Sep 17 00:00:00 2001
From: Jiahao XU <Jiahao_XU@outlook.com>
Date: Thu, 21 Jul 2022 20:41:16 +1000
Subject: [PATCH 2/4] Construct `BinstallError` from `JoinError` in
 `await_task`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
---
 src/helpers.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/helpers.rs b/src/helpers.rs
index 3dc2de96..c5e828bd 100644
--- a/src/helpers.rs
+++ b/src/helpers.rs
@@ -43,7 +43,7 @@ pub use crate_name::CrateName;
 pub async fn await_task<T>(task: tokio::task::JoinHandle<miette::Result<T>>) -> miette::Result<T> {
     match task.await {
         Ok(res) => res,
-        Err(join_err) => Err(miette::miette!("Task failed to join: {}", join_err)),
+        Err(join_err) => Err(BinstallError::from(join_err).into()),
     }
 }
 

From d39bc0acabcf3e8a721314e8446947092ceac45e Mon Sep 17 00:00:00 2001
From: Jiahao XU <Jiahao_XU@outlook.com>
Date: Thu, 21 Jul 2022 20:43:47 +1000
Subject: [PATCH 3/4] Construct `BinstallError` from `JoinError` in `main`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
---
 src/main.rs | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 51847dcb..12ec5126 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -172,13 +172,16 @@ fn main() -> MainExit {
     let done = start.elapsed();
     debug!("run time: {done:?}");
 
-    result.map_or_else(MainExit::JoinErr, |res| {
-        res.map(|_| MainExit::Success(done)).unwrap_or_else(|err| {
-            err.downcast::<BinstallError>()
-                .map(MainExit::Error)
-                .unwrap_or_else(MainExit::Report)
-        })
-    })
+    result.map_or_else(
+        |join_err| MainExit::Error(BinstallError::from(join_err)),
+        |res| {
+            res.map(|_| MainExit::Success(done)).unwrap_or_else(|err| {
+                err.downcast::<BinstallError>()
+                    .map(MainExit::Error)
+                    .unwrap_or_else(MainExit::Report)
+            })
+        },
+    )
 }
 
 async fn entry(jobserver_client: LazyJobserverClient) -> Result<()> {

From adc0a22a50e1983abed44dd8cb0fba1a05a34e78 Mon Sep 17 00:00:00 2001
From: Jiahao XU <Jiahao_XU@outlook.com>
Date: Thu, 21 Jul 2022 20:44:13 +1000
Subject: [PATCH 4/4] Rm unused variant `MainExit::JoinErr`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
---
 src/main.rs | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 12ec5126..9ae6d0f6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -133,7 +133,6 @@ enum MainExit {
     Success(Duration),
     Error(BinstallError),
     Report(miette::Report),
-    JoinErr(JoinError),
 }
 
 impl Termination for MainExit {
@@ -149,11 +148,6 @@ impl Termination for MainExit {
                 eprintln!("{err:?}");
                 ExitCode::from(16)
             }
-            Self::JoinErr(err) => {
-                error!("Fatal error:");
-                eprintln!("{err:?}");
-                ExitCode::from(17)
-            }
         }
     }
 }