Snowflake存储过程使用throw抛错生成额外异常如何解决
问题根因
- 第一个报错(
undefined错误):内部catch块直接抛出字符串类型的err.message,而非Error对象。外层catch捕获到字符串后,读取不存在的message属性就会返回undefined,触发二次错误。 - 第二个报错(绑定参数类型不支持):代码存在多处变量拼写、引用错误,导致插入错误日志的绑定参数值为undefined,不符合Snowflake参数绑定要求,具体错误点包括:
snowflake.cresteStatement拼写错误,应为createStatement- 内部catch块定义变量为
query_id、query_txt,绑定时错误使用了大小写不匹配的queryId、queryText - LOAD_FAILED分支中引用的
result_set、copy_cmd_stmt、err均为未定义变量,对应实际变量应为copy_stmt_result、copy_stmt
修正方案
- 所有throw语句统一抛出Error对象,不要直接抛字符串,保证外层catch可以正常读取错误信息
- 修正所有变量拼写、引用、大小写不匹配的问题
- LOAD_FAILED分支单独构造错误日志参数,不要引用未定义的
err对象
修正后完整代码
returns varchar not null language javascript execute as caller as $$ try { try { var create_table=snowflake.createStatement({sqlText:`create or replace table tableB like tableA`}); create_table.execute(); } catch(err) { var query_id = create_table.getQueryId(); var query_txt = create_table.getSqlText(); var log_insert = snowflake.createStatement({sqlText:`insert into error_table (code, message, queryid, querytext) VALUES (?,?,?,?);` ,binds : [err.code, err.message, query_id, query_txt]}); log_insert.execute(); // 抛出Error对象而非字符串 throw new Error(err.message); } var copy_cmd = `copy into tableb from @myext_stg/<folder> file_format=(format_name='my_csv_format') files=('/file_name') on_error=skip_file;`; var copy_stmt = snowflake.createStatement({sqlText: copy_cmd}) var copy_stmt_result = copy_stmt.execute(); copy_stmt_result.next() if(copy_stmt_result.getColumnValue(2)=='LOADED') { var swap_cmd = `alter table tableB swap with tableA;`; var swap_stmt = snowflake.createStatement({sqlText: swap_cmd}); swap_stmt.execute(); // 正常返回符合声明的字符串值 return "SUCCESS"; } else if(copy_stmt_result.getColumnValue(2)=='LOAD_FAILED') { var err_message= copy_stmt_result.getColumnValue(7); var queryId = copy_stmt.getQueryId(); var queryText = copy_stmt.getSqlText(); var log_insert_into=snowflake.createStatement({sqlText:`insert into error_table (code, message, queryid, querytext) VALUES (?,?,?,?);` // 手动指定code,该分支不存在err对象 ,binds : ["LOAD_FAILED", err_message, queryId, queryText] }); log_insert_into.execute(); throw new Error(err_message); } } catch(err) { // 直接抛出原始Error对象,或封装新的Error throw new Error(`final error: ${err.message}`); } $$;
内容的提问来源于stack exchange,提问作者nani
相关产品推荐
相关产品推荐

