@@ -1174,4 +1174,69 @@ mod tests {
1174
1174
assert_eq ! ( processing_job_count, 2 ) ;
1175
1175
assert_eq ! ( queued_job_count, 2 ) ;
1176
1176
}
1177
+
1178
+ #[ tokio:: test]
1179
+ async fn can_handle_worker_panic ( ) {
1180
+ let tree_fs = tree_fs:: TreeBuilder :: default ( )
1181
+ . drop ( true )
1182
+ . create ( )
1183
+ . expect ( "create temp folder" ) ;
1184
+ let pool = init ( & tree_fs. root ) . await ;
1185
+
1186
+ assert ! ( initialize_database( & pool) . await . is_ok( ) ) ;
1187
+ tests_cfg:: queue:: sqlite_seed_data ( & pool) . await ;
1188
+
1189
+ struct PanicWorker ;
1190
+ #[ async_trait:: async_trait]
1191
+ impl BackgroundWorker < ( ) > for PanicWorker {
1192
+ fn build ( _ctx : & crate :: app:: AppContext ) -> Self {
1193
+ Self
1194
+ }
1195
+ async fn perform ( & self , _args : ( ) ) -> crate :: Result < ( ) > {
1196
+ panic ! ( "intentional panic for testing" ) ;
1197
+ }
1198
+ }
1199
+
1200
+ let mut registry = JobRegistry :: new ( ) ;
1201
+ assert ! ( registry
1202
+ . register_worker( "PanicJob" . to_string( ) , PanicWorker )
1203
+ . is_ok( ) ) ;
1204
+
1205
+ // Get the initial job state
1206
+ let job = get_job ( & pool, "01JDM0X8EVAM823JZBGKYNBA85" ) . await ;
1207
+ assert_eq ! ( job. status, JobStatus :: Queued ) ;
1208
+
1209
+ // Start the worker
1210
+ let opts = RunOpts {
1211
+ num_workers : 1 ,
1212
+ poll_interval_sec : 1 ,
1213
+ } ;
1214
+ let handles = registry. run ( & pool, & opts) ;
1215
+
1216
+ // Wait a bit for the worker to process the job
1217
+ sleep ( Duration :: from_secs ( 1 ) ) . await ;
1218
+
1219
+ // Stop the worker
1220
+ for handle in handles {
1221
+ handle. abort ( ) ;
1222
+ }
1223
+
1224
+ // Verify the job is marked as failed
1225
+ let failed_job = get_job ( & pool, "01JDM0X8EVAM823JZBGKYNBA85" ) . await ;
1226
+ assert_eq ! ( failed_job. status, JobStatus :: Failed ) ;
1227
+
1228
+ // Print and verify the error message stored in job data
1229
+ println ! ( "Job data: {:?}" , failed_job. data) ;
1230
+ let error_msg = failed_job
1231
+ . data
1232
+ . as_object ( )
1233
+ . and_then ( |obj| obj. get ( "error" ) )
1234
+ . and_then ( |v| v. as_str ( ) )
1235
+ . expect ( "Expected error message in job data" ) ;
1236
+ assert ! (
1237
+ error_msg. contains( "intentional panic for testing" ) ,
1238
+ "Error message '{}' did not contain expected text" ,
1239
+ error_msg
1240
+ ) ;
1241
+ }
1177
1242
}
0 commit comments