@@ -264,7 +264,7 @@ fn escape_python_double_quoted(value: &str) -> String {
264264 value. replace ( '\\' , "\\ \\ " ) . replace ( '"' , "\\ \" " )
265265}
266266
267- fn extract_script_metadata_deps ( script : & str ) -> Vec < String > {
267+ fn extract_script_metadata_deps ( script : & str ) -> Result < Vec < String > > {
268268 let mut ss = String :: new ( ) ;
269269 let mut meta_start = false ;
270270 for line in script. lines ( ) {
@@ -280,18 +280,45 @@ fn extract_script_metadata_deps(script: &str) -> Vec<String> {
280280 }
281281 }
282282
283- let parsed = ss. parse :: < toml:: Value > ( ) . unwrap ( ) ;
283+ let parsed = ss. parse :: < toml:: Value > ( ) . map_err ( |err| {
284+ ErrorCode :: SemanticError ( format ! (
285+ "Failed to parse UDF script metadata as TOML: {err}"
286+ ) )
287+ } ) ?;
284288
285289 if parsed. get ( "dependencies" ) . is_none ( ) {
286- return Vec :: new ( ) ;
290+ return Ok ( Vec :: new ( ) ) ;
287291 }
288292
289- if let Some ( deps) = parsed[ "dependencies" ] . as_array ( ) {
293+ let deps = if let Some ( deps) = parsed[ "dependencies" ] . as_array ( ) {
290294 deps. iter ( )
291295 . filter_map ( |value| value. as_str ( ) . map ( |item| item. to_string ( ) ) )
292296 . collect ( )
293297 } else {
294298 Vec :: new ( )
299+ } ;
300+ Ok ( deps)
301+ }
302+
303+ #[ cfg( test) ]
304+ mod tests {
305+ use super :: * ;
306+
307+ #[ test]
308+ fn test_extract_script_metadata_deps_returns_error_for_malformed_toml ( ) {
309+ let err = extract_script_metadata_deps (
310+ r#"# /// script
311+ # dependencies = [
312+ # ///
313+ "# ,
314+ )
315+ . expect_err ( "malformed UDF script metadata should return an error" ) ;
316+
317+ assert_eq ! ( err. code( ) , ErrorCode :: SEMANTIC_ERROR ) ;
318+ assert ! (
319+ err. message( )
320+ . contains( "Failed to parse UDF script metadata as TOML" )
321+ ) ;
295322 }
296323}
297324
@@ -607,7 +634,7 @@ impl UdfAdapter for FullTypeCheckAdapter {
607634 ErrorCode :: SemanticError ( format ! ( "Failed to parse UDF code as utf-8: {err}" ) )
608635 } ) ?;
609636 let import_assets = self . build_udf_cloud_imports ( & imports) ?;
610- let mut merged_packages = extract_script_metadata_deps ( & resolved_code) ;
637+ let mut merged_packages = extract_script_metadata_deps ( & resolved_code) ? ;
611638 merged_packages. extend_from_slice ( & packages) ;
612639 let input_types = arg_types. iter ( ) . map ( udf_type_string) . collect :: < Vec < _ > > ( ) ;
613640 let result_type = udf_type_string ( & return_type) ;
0 commit comments