chiark / gitweb /
panic handling in webserver task too
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 22 Aug 2021 17:12:12 +0000 (18:12 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 22 Aug 2021 17:12:12 +0000 (18:12 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
server/server.rs
src/prelude.rs

index a10961e2ac81ff3ec6d38f22e098d9904f1f1d83..9ce63aaea8190782d4147f4c2be9e33d423a3ca6 100644 (file)
@@ -165,7 +165,13 @@ async fn main() {
           let global_ = global_.clone();
           let conn = Arc::new(format!("[{}]", conn.remote_addr()));
           async { Ok::<_, Void>( hyper::service::service_fn(move |req| {
-            sweb::handle(conn.clone(), global_.clone(), req)
+            AssertUnwindSafe(
+              sweb::handle(conn.clone(), global_.clone(), req)
+            )
+              .catch_unwind()
+              .map(|r| r.unwrap_or_else(|_|{
+                crash(Err("panicked".into()), "webserver request task")
+              }))
           }) ) }
         }
       );
@@ -200,8 +206,14 @@ async fn main() {
   ).await;
 
   let task = &tasks[died_i].1;
-  match output {
-    Err(je) => error!("task panicked! {}: {}", task, &je),
-    Ok(e)    => error!("task failed! {}: {}",  task, &e),
+  let output = output.map_err(|je| je.to_string());
+  crash(output, task);
+}
+
+pub fn crash(what_happened: Result<AE, String>, task: &str) -> ! {
+  match what_happened {
+    Err(je) => error!("task crashed! {}: {}", task, &je),
+    Ok(e)   => error!("task failed! {}: {}",   task, &e ),
   }
+  process::exit(12);
 }
index c7c53e15012320cbfb205c650daf56995a4eff98..9e56662a7ec5f8060112e888aaa294e68199c8ff 100644 (file)
@@ -17,7 +17,7 @@ pub use std::iter;
 pub use std::mem;
 pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
 pub use std::path::{Path, PathBuf};
-pub use std::panic;
+pub use std::panic::{self, AssertUnwindSafe};
 pub use std::process;
 pub use std::pin::Pin;
 pub use std::str::{self, FromStr};
@@ -46,7 +46,7 @@ pub use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
 pub use tokio::pin;
 pub use tokio::select;
 pub use tokio::sync::{mpsc, oneshot};
-pub use tokio::task::{self, JoinHandle};
+pub use tokio::task::{self, JoinError, JoinHandle};
 pub use tokio::time::{Duration, Instant};
 pub use void::{self, Void, ResultVoidExt, ResultVoidErrExt};