
Jina Reader credential validation leaks JSONDecodeError for non-JSON error responses
快速结论:当配置 Jina Reader 凭证时,如果远端或中间代理返回非 2xx 状态码(如 HTTP 403)且响应体不是 JSON 格式(如纯文本 Forbidden),Dify 的 JinaAuth._handle_error() 方法会抛出原生的 json.JSONDecodeError,导致授权失败原因被掩盖。优先排查 _handle_error 函数中是否对非 JSON 响应体做了降级处理。
问题场景
在 Dify 中配置 Jina Reader 工具的 Bearer 认证凭证时,进行凭证校验(credential validation)操作。
报错原文
json.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
原因分析
Dify 的 JinaAuth._handle_error() 方法(位于 api/services/auth/jina/jina.py 第 44-52 行)在处理非 2xx 响应时,有两处 JSON 解析操作未经 try/except 保护:
- 第 46 行:
response.json() - 第 50 行:
json.loads(response.text)
当上游 Jina 端点或中间代理返回 403/Forbidden 这类非 JSON 格式的响应体时,这两行代码都会抛出 JSONDecodeError,中断了原本应构造的受控授权错误信息。
环境排查
- Dify 版本:
main分支 commitb6b9165d - 部署方式:Self Hosted(源码部署)
- 受影响文件:
api/services/auth/jina/jina.pyapi/services/auth/jina.py(存在相同问题的副本文件)
解决步骤
- 打开
api/services/auth/jina/jina.py文件,找到_handle_error(self, response)函数。 - 将原先直接调用
response.json()和json.loads(response.text)的逻辑,替换为 try/except 包裹的降级处理(可优先尝试以下修改):def _handle_error(self, response): if response.status_code in {402, 409, 500}: try: error_message = response.json().get("error", "Unknown error occurred") except Exception: error_message = response.text or "Unknown error occurred" raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") else: if response.text: try: error_message = json.loads(response.text).get("error", "Unknown error occurred") except (json.JSONDecodeError, ValueError): error_message = response.text raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") raise Exception(f"Unexpected error occurred while trying to authorize. Status code: {response.status_code}") - 对
api/services/auth/jina.py文件中的相同函数应用同样的修正。
验证方法
- 重新触发凭证校验流程,确保 Jina 端点或代理在返回非 2xx 状态码时(如 403),不会抛出
JSONDecodeError。 - 检查错误信息是否变为受控的
Failed to authorize. Status code: 403. Error: Forbidden格式,且 HTTP 状态码和响应正文正确显示。



