
在使用Snowflake外部函数时,开发者可能会遇到一个令人困惑的错误:JavaScript execution error: Uncaught SyntaxError: "[object Object]" is not valid JSON in RESPONSE_TRANSLATOR at '[object Object]' position 1。这个错误通常发生在响应转换器尝试处理由外部服务(如AWS Lambda)返回的响应时。
问题的核心在于对EVENT对象中body属性的理解。在Snowflake中,当一个外部函数被调用时,它会向外部API发送请求。外部API的响应(例如,一个Lambda函数的响应)通常是一个包含statusCode、headers和body字段的JSON对象。当这个响应被传递给Snowflake的response_translator函数时,EVENT参数的结构会根据外部API的实际返回而定。
考虑以下原始的响应转换器代码:
CREATE OR REPLACE FUNCTION response_translator(EVENT OBJECT)
RETURNS OBJECT
LANGUAGE JAVASCRIPT AS
'
const parsedJson = JSON.parse(EVENT.body); // 错误发生在这里
const parsedJsonString = JSON.stringify(parsedJson);
const modifiedJson = {
"data": [
[0, parsedJsonString]
]
};
return modifiedJson;
';当开发者直接使用select response_translator(parse_json('...'))来测试转换器,并手动构造一个EVENT对象,其中body字段是一个字符串时,上述代码可能正常工作。例如:
select response_translator(parse_json(' {"body": "{\"error\":{\"grpc_code\":5,\"http_code\":404,\"message\":\"Resource not found\",\"http_status\":\"Not Found\"}}"
}'));在这个模拟场景中,EVENT.body确实是一个JSON字符串,JSON.parse(EVENT.body)能够成功执行。
然而,当通过select test('abc123');触发外部函数时,如果外部API(例如Lambda)的响应如下:
{
"statusCode": 200,
"headers": null,
"multiValueHeaders": null,
"body": "{"error":{"grpc_code":5,"http_code":404,"message":"Resource not found","http_status":"Not Found"}}"
}Snowflake接收到这个完整的JSON响应后,会将其解析成一个JavaScript OBJECT,然后将该对象的各个字段映射到EVENT参数中。这意味着,当外部函数实际调用response_translator时,EVENT.body可能已经是一个JavaScript对象,而不是一个需要进一步解析的JSON字符串。此时,对一个已经解析过的JavaScript对象调用JSON.parse()会导致Uncaught SyntaxError: "[object Object]" is not valid JSON错误,因为JSON.parse()期望一个字符串作为输入。
问题的根本原因在于对EVENT.body在不同调用场景下数据类型的误解。
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
30
场景一:直接模拟调用 当使用parse_json('{"body": "..."}')构造EVENT时,如果body字段的值本身是一个包含转义字符的JSON字符串,那么在JavaScript中,EVENT.body将是一个字符串。此时JSON.parse(EVENT.body)是正确的操作。
场景二:外部函数实际调用 当外部函数调用外部API并接收到响应时,Snowflake会尝试将整个HTTP响应(包括statusCode、headers和body字段)解析为JavaScript EVENT对象的属性。如果外部API的body字段本身包含一个有效的JSON字符串(例如"{"error":...}"),Snowflake的内部机制可能会将其自动解析成一个JavaScript对象,然后再赋值给EVENT.body。
因此,在实际的外部函数调用流程中,EVENT.body很可能已经是一个JavaScript对象([object Object]),而不是一个字符串。试图对一个JavaScript对象再次调用JSON.parse()是无效的,因为JSON.parse()只接受JSON格式的字符串。
正确的做法是检查EVENT.body的类型。如果它已经是一个对象,则直接访问其属性;如果它是一个JSON字符串,则需要先进行解析。然而,在Snowflake外部函数的上下文中,为了简化和避免类型检查的复杂性,更直接的方法是假设Snowflake已经将API响应的body字段(如果其内容是有效JSON)解析成了JavaScript对象。
因此,我们应该直接访问EVENT.body的属性,而不是尝试再次解析它。以下是修正后的response_translator函数:
CREATE OR REPLACE FUNCTION response_translator(EVENT OBJECT)
RETURNS OBJECT
LANGUAGE JAVASCRIPT AS
'
// 检查 EVENT.body 是否存在错误信息
// 假设 EVENT.body 已经是一个 JavaScript 对象
if (EVENT.body && EVENT.body.error != null) {
const modifiedJson = {
"data": [
[0, EVENT.body] // 直接将 EVENT.body 作为对象存储
]
};
return modifiedJson;
}
// 如果没有错误,或者需要处理其他成功的响应体,则添加相应逻辑
// 例如,如果成功响应的 body 是 {"result": "success"},则可以这样处理:
// if (EVENT.body && EVENT.body.result != null) {
// const modifiedJson = {
// "data": [
// [0, EVENT.body.result]
// ]
// };
// return modifiedJson;
// }
// 默认返回一个空的或指示错误的结构,以防未处理的情况
return { "data": [[0, null]] };
';代码解释:
通过这种方式,我们避免了对一个已经解析过的对象再次调用JSON.parse(),从而解决了Uncaught SyntaxError。
Uncaught SyntaxError: "[object Object]" is not valid JSON错误在Snowflake外部函数响应转换器中是一个常见的陷阱,它源于对EVENT.body数据类型在不同调用场景下的误解。通过认识到在实际外部函数调用中,EVENT.body很可能已经是一个JavaScript对象,我们应该直接访问其属性,而不是尝试再次解析它。遵循本教程提供的修正方案和最佳实践,可以有效避免此类错误,并构建出健壮可靠的Snowflake外部函数。
以上就是Snowflake外部函数响应转换器JSON解析错误排查与修复的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号