]> git.proxmox.com Git - proxmox-backup.git/commitdiff
src/server/worker_task.rs: catch panics in worker threads
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 11 Apr 2019 05:55:02 +0000 (07:55 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 11 Apr 2019 05:56:06 +0000 (07:56 +0200)
src/server/worker_task.rs

index 5abca6e323db7242a9b59b670a112a052ffd0334..67e97fc1a0d5c5293a31f24273ec055538495987 100644 (file)
@@ -9,6 +9,8 @@ use std::collections::HashMap;
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::io::{BufRead, BufReader};
 use std::fs::File;
+use std::panic::UnwindSafe;
+
 use serde_json::{json, Value};
 
 use super::UPID;
@@ -426,7 +428,7 @@ impl WorkerTask {
         to_stdout: bool,
         f: F,
     ) -> Result<String, Error>
-        where F: Send + 'static + FnOnce(Arc<WorkerTask>) -> Result<(), Error>
+        where F: Send + UnwindSafe + 'static + FnOnce(Arc<WorkerTask>) -> Result<(), Error>
     {
         println!("register worker thread");
 
@@ -437,7 +439,22 @@ impl WorkerTask {
         let upid_str = worker.upid.to_string();
 
         let _child = std::thread::spawn(move || {
-            let result = f(worker.clone());
+            let worker1 = worker.clone();
+            let result = match std::panic::catch_unwind(move || f(worker1)) {
+                Ok(r) => r,
+                Err(panic) => {
+                    match panic.downcast::<&str>() {
+                        Ok(panic_msg) => {
+                            Err(format_err!("worker panicked: {}", panic_msg))
+                        }
+                        Err(_) => {
+                            Err(format_err!("worker panicked: unknown type."))
+                        }
+                    }
+                }
+            };
+
+            //let result = f(worker.clone());
             WORKER_TASK_LIST.lock().unwrap().remove(&task_id);
             worker.log_result(result);
             let _ = update_active_workers(None);