From 7af010cb96b9af0c7f7f664a15e836cbd2931244 Mon Sep 17 00:00:00 2001 From: Taku Fukada Date: Tue, 28 May 2024 23:38:47 +0900 Subject: [PATCH] catch pipeline joining errors --- app/src-tauri/src/main.rs | 6 ++++- nusamai/src/main.rs | 5 +++- nusamai/src/pipeline/runner.rs | 27 ++++++++++++++----- nusamai/src/sink/shapefile/attributes.rs | 5 +++- .../transformer/transform/shp_field_dict.json | 18 ++++++++++++- nusamai/tests/mod.rs | 1 - nusamai/tests/pipeline.rs | 2 +- nusamai/tests/sink.rs | 2 +- 8 files changed, 52 insertions(+), 14 deletions(-) delete mode 100644 nusamai/tests/mod.rs diff --git a/app/src-tauri/src/main.rs b/app/src-tauri/src/main.rs index c27925c66..789e6128e 100644 --- a/app/src-tauri/src/main.rs +++ b/app/src-tauri/src/main.rs @@ -260,7 +260,11 @@ fn run_conversion( .unwrap(); // Wait for the pipeline to finish - handle.join(); + if let Err(msg) = handle.join() { + return Err(Error::ConversionFailed(format!( + "Pipeline thread panicked: {msg}" + ))); + } // Return error if an error occurred in the pipeline if let Some(err) = first_error { diff --git a/nusamai/src/main.rs b/nusamai/src/main.rs index f5381aa85..be223fe55 100644 --- a/nusamai/src/main.rs +++ b/nusamai/src/main.rs @@ -283,7 +283,10 @@ fn run( }); // wait for the pipeline to finish - handle.join(); + if let Err(msg) = handle.join() { + log::error!("Pipeline thread panicked: {:?}", msg); + } + if canceller.lock().unwrap().is_canceled() { log::info!("Pipeline canceled"); } diff --git a/nusamai/src/pipeline/runner.rs b/nusamai/src/pipeline/runner.rs index 9948887eb..35a7628ee 100644 --- a/nusamai/src/pipeline/runner.rs +++ b/nusamai/src/pipeline/runner.rs @@ -110,16 +110,29 @@ pub struct PipelineHandle { impl PipelineHandle { // Wait for the pipeline to terminate - pub fn join(self) { - if self.source_thread_handle.join().is_err() { - log::error!("Source thread panicked"); + pub fn join(self) -> Result<(), String> { + fn report_error(stage: &str, err: Box) -> String { + let msg = if let Some(message) = err.downcast_ref::<&str>() { + format!("{stage} thread panicked with message: {}", message) + } else if let Some(string) = err.downcast_ref::() { + format!("{stage} thread panicked with message: {}", string) + } else { + format!("{stage} thread panicked with an unknown type.") + }; + log::error!("{}", msg); + msg.to_string() } - if self.transformer_thread_handle.join().is_err() { - log::error!("Transformer thread panicked"); + + if let Err(err) = self.source_thread_handle.join() { + return Err(report_error("Source", err)); + } + if let Err(err) = self.transformer_thread_handle.join() { + return Err(report_error("Transformer", err)); } - if self.sink_thread_handle.join().is_err() { - log::error!("Sink thread panicked"); + if let Err(err) = self.sink_thread_handle.join() { + return Err(report_error("Sink", err)); } + Ok(()) } } diff --git a/nusamai/src/sink/shapefile/attributes.rs b/nusamai/src/sink/shapefile/attributes.rs index 7b4b3fa21..75e5e5230 100644 --- a/nusamai/src/sink/shapefile/attributes.rs +++ b/nusamai/src/sink/shapefile/attributes.rs @@ -24,7 +24,10 @@ pub fn make_table_builder( }; for (field_name, attr) in attributes { - let name = field_name.as_str().try_into().unwrap(); // FIXME: handle errors + let Ok(name) = field_name.as_str().try_into() else { + log::error!("Field name '{}' cannot be used in Shapefile", field_name); + continue; + }; let key = field_name.to_string(); match attr.type_ref { diff --git a/nusamai/src/transformer/transform/shp_field_dict.json b/nusamai/src/transformer/transform/shp_field_dict.json index b1f82a670..3b18f0ef7 100644 --- a/nusamai/src/transformer/transform/shp_field_dict.json +++ b/nusamai/src/transformer/transform/shp_field_dict.json @@ -847,5 +847,21 @@ "zonalDisasterPreventionFacilities": "zoneDPFacl", "zonalDisasterPreventionFacilitiesAllocation": "zDiPrFcAlc", "zoneName": "zoneName", - "zoneNumber": "zone#" + "zoneNumber": "zone#", + "geometrySrcDesc0": "geomSrcD0", + "geometrySrcDesc1": "geomSrcD1", + "geometrySrcDesc2": "geomSrcD2", + "geometrySrcDesc3": "geomSrcD3", + "geometrySrcDesc4": "geomSrcD4", + "appearanceSrcDescLod0": "appSDLod0", + "appearanceSrcDescLod1": "appSDLod1", + "appearanceSrcDescLod2": "appSDLod2", + "appearanceSrcDescLod3": "appSDLod3", + "appearanceSrcDescLod4": "appSDLod4", + "tranDataAcquisition": "tranDtaAcq", + "publicSurveyDataQualityAttribute": "pubSvDQual", + "bldgUsecaseAttribute": "bldgUC", + "frnKeyValuePairAttribute": "frnKVPair", + "tranKeyValuePairAttribute": "tranKVPair", + "tranUsecaseAttribute": "tranUC" } \ No newline at end of file diff --git a/nusamai/tests/mod.rs b/nusamai/tests/mod.rs deleted file mode 100644 index 4f919315d..000000000 --- a/nusamai/tests/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod sink; diff --git a/nusamai/tests/pipeline.rs b/nusamai/tests/pipeline.rs index 53055977b..613cff1a8 100644 --- a/nusamai/tests/pipeline.rs +++ b/nusamai/tests/pipeline.rs @@ -162,5 +162,5 @@ fn test_run_pipeline() { }); // wait for the pipeline to finish - handle.join(); + handle.join().unwrap(); } diff --git a/nusamai/tests/sink.rs b/nusamai/tests/sink.rs index e95bff808..17a70abd8 100644 --- a/nusamai/tests/sink.rs +++ b/nusamai/tests/sink.rs @@ -64,7 +64,7 @@ pub(crate) fn simple_run_sink(sink_provider: S, output: Opt let (handle, watcher, canceller) = nusamai::pipeline::run(source, transformer, sink, schema.into()); - handle.join(); + handle.join().unwrap(); for msg in watcher { println!("Feedback message from the pipeline {:?}", msg);