电子邮件账户显示“凭据无效”或SMTP/IMAP认证错误

当您保存电子邮件账户,或者当 Frappe 通过某个电子邮件账户发送和接收邮件时,邮件服务器可能会拒绝登录。您会看到保存错误、电子邮件账户被禁用,或者邮件卡在队列中。

错误信息

根据登录被拒绝的位置,您会看到以下其中一种情况:

保存时,来自发送服务器

Incorrect Configuration
Invalid credentials for Email Account
Incorrect Configuration
Invalid Outgoing Mail Server or Port: Connection unexpectedly closed

在计划同步时,来自接收服务器

Authentication failed while receiving emails from Email Account: <name>.
Message from server: b'[AUTHENTICATIONFAILED] Invalid credentials (Failure)'
</name>

来自第三方 SMTP 中继,出现在错误日志中

smtplib.SMTPSenderRefused: (502, b'5.7.0 Please authenticate first', ...)

保存时对话框的样子——冒号后面的措辞取决于拒绝连接的对象。

这四种情况含义相同:服务器不接受您提供的登录 ID 和密码。具体措辞取决于失败发生在保存时(发送)还是计划同步期间(接收),以及您的服务商如何报告该问题。

为什么会发生这种情况

当您保存电子邮件账户时,Frappe 会使用您输入的登录 ID、密码、服务器、端口和加密方式(TLS 或 SSL)连接到邮件服务器,并尝试进行身份验证。只有当所有这些都与服务器期望的一致时,服务器才会接受登录。密码错误、端口与加密方式不匹配,或者服务商不再允许使用普通密码的登录流程(Gmail 和 Microsoft 现在都要求这样做),都会返回同一种拒绝。

如果电子邮件账户之前一直正常工作,后来开始失败,通常的原因是服务商那边更改了密码,或者启用了双重身份验证(2FA),这会使 Frappe 等应用使用的账户密码失效。

如何修复

1. 检查基本设置

  1. 打开电子邮件账户,滚动到身份验证部分(服务器字段则在发送(SMTP)设置中)。
  2. 如果账户登录所用的地址与发送时使用的地址不同,请勾选使用不同的电子邮件 ID,并在备用电子邮件 ID中输入真实的登录信息。
  3. 重新输入密码。复制粘贴的密码可能带有尾部空格或换行符,从而导致与密码错误相同的错误。
  4. 对照服务商公布的信息,检查发送服务器(或电子邮件服务器)和端口。
  5. 检查使用 TLS和使用 SSL——只应勾选其中一项,并且必须与端口匹配:
  • 端口 587 → 勾选使用 TLS,取消勾选使用 SSL。
  • 端口 465 → 勾选发送使用 SSL,取消勾选使用 TLS。

在同一端口下两项都勾选或两项都不勾选,本身就是导致此错误的常见原因。

发送(SMTP)设置——使用 TLS 和端口已用方框标出,这是最常出现不匹配的一对设置。

如果使用 TLS和使用 SSL呈灰色且无法更改,说明该电子邮件账户已关联到一个电子邮件域。发送设置来自该电子邮件域,而不是来自账户。请打开关联的电子邮件域进行更改,或者清除电子邮件账户上的域字段,以便改为在那里解锁这些字段。

2. 适用于 Gmail 或 Google Workspace

Google 不再接受您的普通账户密码用于 Frappe 或任何非 Google 产品的应用。将服务设置为GMail——这会自动填入 IMAP/SMTP 服务器、端口和加密方式——然后使用以下其中一种方式:

将服务设置为 GMail 会预设服务器、端口和加密方式。

  • 应用专用密码。在 myaccount.google.com/security 为 Google 账户开启两步验证,然后在同一页面生成应用专用密码,并将其用作电子邮件账户的密码,而不是您的登录密码。应用专用密码只有在开启两步验证后才有效。如果 2FA 未开启,Google 不会允许您生成应用专用密码,账户会继续拒绝普通密码。
  • OAuth,如果您完全不想存储密码。这需要在 Google Cloud 中设置一个已连接应用,并将其选为电子邮件账户的身份验证方法。设置流程与 Microsoft Office365 电子邮件 OAuth 相同——一个已连接应用、一个重定向 URI,以及用于 IMAP 和 SMTP 的邮件作用域。

3. 适用于第三方 SMTP 服务商(SMTP2Go、Brevo、Sendgrid 等)

这些服务商完全不使用您的电子邮件收件箱密码。它们会签发自己的 SMTP 用户名和 API 密钥,与任何账户登录信息分开:

  1. 在服务商的控制面板中,找到(或生成)用于发送邮件的SMTP 用户名和SMTP 密码 / API 密钥。例如,对于 Sendgrid,SMTP 用户名就是 apikey,密码是生成的 API 密钥,而不是账户密码。
  2. 在电子邮件账户上,勾选使用不同的电子邮件 ID,并在其中输入服务商的 SMTP 用户名。
  3. 将 API 密钥输入为密码。
  4. 请完全按照提供商文档中的说明输入传出服务器和端口,并与第 1 步中该端口对应的 使用 TLS / 使用 SSL 设置保持一致。

如果你专门使用 Brevo,并且在匹配上述所有设置后仍然遇到 (502, b'5.7.0 Please authenticate first'),你的站点可能需要 smtp_no_ehlo_after_auth 站点配置键——某些中继会拒绝 Python 的 SMTP 客户端在登录后发送的额外 EHLO 命令。从 Frappe v16.17.0 起,此问题已默认修复。在更早的版本上,请提交支持工单并引用此错误。

4. 在 Frappe 之外测试凭据

在再次保存电子邮件账户之前,请先确认登录本身可以正常工作:

  • 在你的电子邮件客户端(Outlook、Thunderbird、Gmail 或 Outlook 网页应用)中,使用相同的服务器、端口、加密方式和密码添加同一账户。如果在那里也失败,则问题出在凭据或提供商,而不是 Frappe。

  • 如果你有 shell 访问权限,请直接测试 SMTP 登录:

    openssl s_client -connect smtp.gmail.com:587 -starttls smtp
    

    然后输入 EHLO、AUTH LOGIN,以及 base64 编码的登录 ID 和密码。返回 235 响应表示登录成功。返回 535 或 534 响应表示服务器拒绝了登录。

一旦登录在 Frappe 之外可以正常工作,请返回电子邮件账户并使用相同的值再次保存。

检查失败后发生了什么

登录失败并不总是立即以对话框形式显示。请检查以下两个位置:

  • 电子邮件队列:打开电子邮件队列列表并按 状态 = 错误 筛选。打开失败的行,查看服务器针对该特定电子邮件返回的拒绝消息。
  • 错误日志:如果电子邮件账户被自动禁用(在计划同步中反复出现身份验证失败后会发生这种情况),请在错误日志列表中搜索其被禁用时间附近的完整回溯信息,然后在修复凭据后重新启用该电子邮件账户。

如何预防

  • 为 Gmail 和 Microsoft 账户开启双重验证并改用应用密码(或 OAuth),以免在提供商强制更改之前措手不及。
  • 当提供商的密码或 API 密钥轮换时,请在同一天更新电子邮件账户——过期的密码会使账户保持禁用状态,并悄无声息地停止通知、欢迎电子邮件和警报。

如果这不能解决问题

如果登录在 Frappe 之外成功,但在电子邮件账户上仍然失败,请提交支持工单并附上:确切的错误文本、电子邮件账户名称,以及失败发生在 保存、传出发送还是 传入同步时。

  • 电子邮件账户
  • 电子邮件域
  • 在 ERPNext 中设置 Sendgrid SMTP 电子邮件
  • Microsoft Office365 电子邮件 OAuth

更新后打印失败,提示“’NoneType’ object is not callable”或Jinja错误

突然间,就在一次 Frappe 更新之后,你一打开打印视图或尝试下载 PDF,所有打印格式(或某个特定格式)就立刻报错。错误信息只给出了行号,却没有说明是哪个格式,所以很难看出该修什么。

错误信息

你会看到下面其中一种,可能出现在打印视图的对话框中,也可能出现在 PDF/下载的响应里:

Print Format Error

Error in print format on line 19: 'NoneType' object is not callable

或者是更完整的版本,出现在你从 PDF 下载链接得到的服务器错误页面中:

File "apps/frappe/frappe/templates/print_formats/standard.html", line 19, in top-level template code

{{ render_field(df, doc, no_of_cols) }}

File "env/lib/python3.x/site-packages/jinja2/sandbox.py", line 401, in call

return __context.call(__obj, *args, **kwargs)

TypeError: 'NoneType' object is not callable

...

frappe.exceptions.PrintFormatError: Error in print format on line 19: 'NoneType' object is not callable

还有一种相关的情况,显示的是 KeyError 或其他 Jinja 异常,而不是 NoneType,但同样呈现“所有打印格式都挂了”的模式。原因和下面的修复方法是一样的。

为什么会这样

打印格式是通过 Jinja 渲染的:html 模板通过 Jinja 的沙箱调用 Python 函数并读取文档字段。'NoneType' object is not callable 的意思是 Jinja 试图把某个东西当作函数来调用,但那个东西的值是 None——通常是一个空字段(当 备注 为空时就是 {{ doc.remarks() }}),或者是沙箱无法解析的模板宏。

大多数“更新后所有打印格式都坏了”的报告,都能追溯到 Frappe Framework 本身的一次短暂回归,出在 standard.html 模板上——所有内置打印格式和基于 Builder 的打印格式都共用这个模板。一次核心改动导致其中一个模板宏在两个版本之间的短暂窗口内返回了 None。Frappe 修复这类问题很快(几小时到几天内),并以补丁版本发布修复,但在你的站点升级到那个版本之前,所有打印和 PDF 都会以同样的方式失败。同一个模板上已经不止一次发生过这种情况,所以“先更新看看是否修好了”是合理的第一步,而不是一次性的做法。

如果只有 一个 打印格式失败,其余都正常,那原因就在这个格式本身:某个自定义打印格式(或合作伙伴定制过的格式)的 Jinja 或自定义 HTML 调用了某个字段、doctype 方法或打印模板钩子,而应用更新把它删除了、重命名了,或者对某些文档留空了。

如何修复

  1. 打开文档,点击打印图标,把 打印格式 切换到另一个(内置格式,或 标准)。如果它能正常渲染,问题就出在你原来用的那个格式上——跳到第 4 步。如果所有格式都失败,问题就在 Frappe 本身——继续第 2 步。


  2. 阅读 traceback,确认它与本问题相符,并找出失败的位置。在打印视图中,重新选择出错的格式以查看对话框;从 PDF 下载链接(或附带 PDF 的邮件/报表)打开完整的服务器错误页面——那里有完整的 traceback。


最后一行会给出异常名称,如果是打印格式特有的错误,还会给出你模板中的行号:


如果失败发生在后台任务中(定时报表、附带 PDF 的邮件)——也就是没有人能看到对话框——请从 Awesome Bar 打开 错误日志,查找同一文档在相近时间的记录;它带有相同的 traceback。
3. 检查你的应用是否都在匹配的、最新的版本上。打开 帮助 → 关于(或在 bench 目录下运行 bench version),对比 已安装应用 列表:Frappe Framework、你的主应用(ERPNext 等)以及任何自定义应用都应该在同一条版本线上(全是 v15,或全是 v16——不能混用),而且都不应落后于该版本线的最新补丁版本。


如果 Frappe Framework 落后了,就更新它:

bench update

bench --site [site-name] migrate

bench build

bench clear-cache

bench clear-website-cache

即使 bench update 无错误地完成,bench build 和两个清除缓存的命令也很重要——过期的 JS/CSS 构建或缓存的页面会继续显示旧的、损坏的行为。在 Frappe Cloud 上,你不需要自己运行这些:公共(共享)bench 会在每周发布日自动更新;在私有 bench 组上,打开站点仪表盘中的 更新 并应用待处理的更新。
4. 如果只有你自己的自定义打印格式失败,打开它(打印格式 列表,或从打印视图点击 自定义),检查 traceback 指出的那一行。查找某个字段引用——它可能对某些文档为空,却被当作函数调用(用 {{ doc.some_field() }} 而不是 {{ doc.some_field }}),或者从某个模板路径导入的宏被应用更新改掉了。修复模板,或者如果这个格式是在更新之前构建的,就按当前的标准布局重新创建它。

如何预防

  • 让 Frappe Framework 和其他应用保持在同一版本线上,并使用该版本线的最新补丁版本——这些故障大多会在某个小版本发布中修复,保持更新即可避免。
  • 任何更新之后,在团队重新开始使用站点之前,先用你依赖的每个自定义打印格式各打印一份文档。

如果这样仍不能解决

提交支持工单,并附上:确切的错误文本、打印格式名称、帮助 → 关于中的 Frappe Framework 和应用版本,以及你当时正在打印的文档。如果你有完整的回溯信息(来自服务器错误页面或错误日志),请一并附上——这是支持人员确认这是已知的 Framework 回归问题还是你自己的打印格式问题的最快方式。

  • 打印
  • 在哪里可以找到标准打印格式

电子发票显示失败、无IRN或无法取消

提交销售发票后,India Compliance 会生成电子发票,并在发票上保存 IRN 和二维码。
本页介绍当电子发票状态显示为失败、IRN 缺失,以及
电子发票无法取消或修改时该怎么办。

提示信息

e-Invoice can only be cancelled upto 24 hours after it is generated

同一问题的其他迹象:电子发票状态为失败或待处理,打印的发票上没有 IRN 或二维码,
或者 GST 门户上显示的电子发票在 ERPNext 中不存在。

工作原理

生成电子发票时,政府门户会返回一个 IRN(发票参考号)和一个
已签名的二维码。India Compliance 会将它们保存在销售发票和电子发票日志中,并将
电子发票状态设置为已生成。

政府只允许在生成电子发票后的 24 小时内取消,且电子发票
永远不能编辑。超过这个时间后,更正需要通过贷项通知单或借项通知单进行。

电子发票状态为失败,或没有 IRN

  1. 打开销售发票,查看电子发票部分或电子发票日志中的错误。
  2. 如果是凭据或 API 错误,请参阅 GST API 错误。
  3. 如果是数据错误(GSTIN、PIN 码、HSN 代码、地址),请更正主数据,然后在
    发票上使用电子发票 → 生成重试。
  4. 如果门户提示 IRN 已存在(重复 IRN),说明电子发票是在之前某次尝试中创建的,
    但 ERPNext 没有记录。请再次使用电子发票 → 生成。如果买方 GSTIN 和发票金额与本发票匹配,
    India Compliance 会获取现有的电子发票并将其关联。如果在GST 设置 → 常规中开启了
    从 GST 门户获取电子发票详情,当电子发票门户未返回详情时,
    它还会到 GST 门户上查找。
  5. 如果错误是 e-Invoice cannot be generated because the posting date exceeds the reporting time limit of … days as specified in GST Settings,说明发票的日期早于电子发票报告时限(天)中设置的
    政府报告期限。该发票已无法再生成电子发票。
    请开具一张日期为今天的新发票,或与您的税务顾问确认该期限。

旧版本中,如果有人从销售发票列表再次生成电子发票,状态会被设置为失败。
此问题已在 India Compliance 15.25.5 中修复。如果您的版本较旧,请更新应用。

电子发票是直接在政府门户上生成的

如果您是在门户上而不是在 ERPNext 中生成或取消电子发票,请在发票上记录:

  • 在门户上生成:电子发票 → 标记为已生成,然后输入 IRN、确认编号
    和日期。
  • 在门户上取消:电子发票 → 标记为已取消,然后输入取消详情。

取消电子发票

在生成后的 24 小时内:

  1. 打开销售发票并点击取消。
  2. 选择随发票一起取消 IRN。如果在 GST 设置中开启了取消发票时自动取消电子发票,
    则会自动执行,无需询问。

超过 24 小时后,门户将不会取消电子发票:

  • 要更正发票,请针对该发票开具贷项通知单,并开具一张信息正确的新发票。
  • 如果无论如何都必须在 ERPNext 中取消销售发票(例如它已在门户上被删除),请关闭
    GST 设置 → 常规中的电子发票不可取消时限制取消,取消
    发票,然后再重新开启该选项。

电子发票不能修改。请取消它并开具新发票,或使用贷项通知单。

发票仅包含零税率或免税项目

GST 设置 → 常规中的电子发票中的零税率 / 免税 / 非 GST 项目决定如何处理:
不生成、随其他费用生成,或随应税金额生成。如果某个项目被错误地显示为
零税率,请检查其项目税务模板和 GST 详情。请参阅为什么我的发票上 GST 错误或缺失?。

使用电子发票打印格式(或包含二维码的自定义格式)打印销售发票。请参阅
打印格式中的电子发票二维码。

  • 印度 GST、电子发票和电子运单:查找您的答案
  • 生成和取消电子发票
  • 电子发票和电子运单常见问题

为什么我的发票在GSTR-1中缺失,或者为什么总额不匹配?

你为某个月运行了 GSTR-1,却发现某张发票没有列出、出现在了你没有预料到的部分,或者
合计金额与你的销售登记簿或电子发票门户不一致。大多数情况下 GSTR-1 是对的:它按照 GST 门户的方式
对发票进行分组。本页说明每种发票归入哪里,以及数据出错时该修复什么。

在哪里查看 GSTR-1

India Compliance 有两个地方:

  • GSTR-1(在搜索栏中搜索“GSTR-1”):为公司、GSTIN 和期间生成申报表,
    将其与 GST 门户比对,并上传或提交。用它来申报。
  • GST Sales Register:每张发票一行,并显示其 GSTR-1 部分。用它来查找单张发票。

参见 India Compliance 中的 GSTR-1。

某张发票没有以其自身编号列出

该发票是 它出现在
向未注册客户(B2C)的销售,在本邦内或低于 B2CL 限额 B2C(其他),表 7,按供应地和税率各汇总为一个合计,而不是逐张发票列出
向未注册客户的跨邦销售,且超过 B2CL 限额(自 2024 年 8 月 1 日起为 ₹1,00,000,此前为 ₹2,50,000) B2C(大额),表 5
向注册客户的贷项通知单或借项通知单 贷项/借项通知单(注册),表 9B,不与发票放在一起
向未注册客户的贷项通知单或借项通知单 贷项/借项通知单(未注册),表 9B
向 SEZ 单位或视同出口的销售 B2B、SEZ、DE,表 4
出口 出口,表 6A,按是否含税支付拆分
零税率、免税或非 GST 零税率、免税、非 GST,表 8

要查找单张发票,请打开该期间的 GST Sales Register,并按发票编号筛选。

某张发票完全缺失

  1. 发票上没有 GST。 如果发票的税费表中没有 GST 行,就没有 GST 明细,因此
    GSTR-1 无法对其进行分类。添加正确的税模板,修改发票,然后再次生成 GSTR-1。
  2. GSTIN 或期间错误。 GSTR-1 按 GSTIN 分别生成。如果公司有多个 GSTIN,请检查
    发票的 Company GSTIN 并选择该 GSTIN。检查发票的过账日期是否在该期间内。
  3. 草稿或已取消。 只包含已提交的发票。
  4. 生成后数据发生更改。 GSTR-1 保留生成时的数据。在你更改
    发票后,请再次生成(或使用 GSTR-1 页面上的 Reset),以便重新计算。

合计金额不一致

  • 两个 GSTIN 被合并。 未按 GSTIN 筛选运行的报表会把公司的所有 GSTIN 加总。请
    用同一个 GSTIN 筛选每份报表。
  • 退货。 HSN 汇总同时包含发票和贷项通知单。B2B 部分不
    包含贷项通知单(它们在 9B 中)。因此两个合计会因贷项通知单而不同。
  • 带税率的零金额发票会向 HSN 汇总添加金额为零的行。
  • GST 被应用了两次。 如果一张发票在两个税费行中具有相同的 GST 科目,GST 会被计算两次。
    修复税模板,然后修改发票。

生成或上传 GSTR-1 失败

  • 凭据错误: 上传使用 Returns API。参见 GST API 错误。
  • HSN 代码错误: 带空格或长度错误的 HSN 代码无法通过 GST 门户的检查。请修复
    物料上和受影响发票上的 HSN 代码,然后再次生成。
  • 在恢复或迁移站点后: 存储的 GST 门户会话和密码无法用
    新的加密密钥读取。请重新输入凭据。
  • 应用版本过旧: 2025 年和 2026 年期间的 India Compliance 版本中修复了多个 GSTR-1 生成错误。请更新应用,并确保站点使用稳定分支(例如 version-16),而不是
    测试版分支。
  • India GST、电子发票和电子运单:查找你的答案
  • India Compliance 中的 GSTR-1
  • GST 报表:Sales Register、Purchase Register、GST Balance

为什么我的发票上消费税错误或缺失?

在销售发票或采购发票上,GST 可能会显示为错误的类型(本应是 CGST 和 SGST 却显示为 IGST,或者反过来)、与你的计算结果相差几派萨,或者根本没有显示。使用 India Compliance 应用时,GST 遵循一小部分设置。本页将逐一说明这些设置以及如何修正问题。

India Compliance 如何确定 GST

  1. 供应地(Place of Supply)决定类型。如果供应地与公司 GSTIN 所在邦相同,发票就会采用 CGST 和 SGST(邦内交易)。如果供应地在另一个邦,则采用 IGST(邦际交易)。
  2. 税务模板决定税率。税额来自与类型匹配的销售税和费用模板(或采购模板),而物料的物料税务模板则设定每个物料的税率。
  3. GST 设置中的GST 科目告诉应用哪些科目是 CGST、SGST 和 IGST。如果没有这些设置,应用就无法将这些税识别为 GST。

类型错误:本应是 CGST 和 SGST 却显示为 IGST,或者反过来

发票上的供应地字段有误。对于销售发票,India Compliance 会从以下来源获取供应地:

  • 账单地址上的客户 GSTIN(如果会计设置 → 确定地址税务类别的依据设为收货地址,则取收货地址上的 GSTIN)
  • 对于未注册的客户,取该地址的 GST 邦
  • 如果两者都不存在,则取公司自己所在的邦,因此发票会变成邦内交易。

当字段为空时,India Compliance 会设置供应地;当你更改表单上的地址时,它也会更新供应地。如果地址是通过其他方式设置的(例如通过导入或 API),供应地可能会保留旧的邦。

修正方法:

  1. 打开发票,检查客户地址(或收货地址)和供应地。
  2. 更正地址:地址需要有 GSTIN,或者对于未注册的客户,需要有 GST 邦。
  3. 在发票上重新选择该地址,以便更新供应地。或者手动设置供应地。
  4. 选择匹配的销售税和费用模板(邦内或邦外)并保存。

对于货物,法律规定供应地为货物移动结束的地点。因此,即使客户在你所在的邦,交付到另一个邦的 B2C 销售也属于邦际交易。

未添加 GST,或者 CGST、SGST 和 IGST 全部加在一起

  • 缺少 GST 科目。转到GST 设置 → 科目,为公司添加一行,填入其 CGST、SGST、IGST 和 Cess 科目。然后在发票上重新选择税务模板。
  • 税额来自物料税务模板。如果会计设置 → 自动从物料税务模板添加税费处于开启状态,ERPNext 会添加物料模板中的每一行税,这可能导致 CGST、SGST 和 IGST 同时出现。India Compliance 需要将此设置关闭。将其关闭,然后重新选择税务模板。该设置的工作原理:物料税务模板。
  • 发票上没有税务模板。选择邦内或邦外模板,或者为公司设置一个默认模板。

GST 与你的计算结果相差几派萨

India Compliance 按物料计算 GST 并进行舍入。舍入差额会加到最后一个物料上,因此某个物料的税额看起来可能有误,但总额是正确的。

  • 系统设置中的舍入方法决定数值如何舍入。“银行家舍入法(旧版)”会产生意外结果;“商业舍入法”会按大多数人的预期将 .5 向上舍入。发票会保留保存时所用的方法。
  • GST 设置 → 常规中的舍入 GST 值会将每个 GST 组成部分(CGST、SGST、IGST)舍入为整卢比,外币发票除外。如果你需要精确到派萨的 GST,请将其关闭。
  • 外币发票会换算每笔金额,因此以 INR 计的 GST 可能与 INR 金额 × 税率相差几派萨。

一些舍入错误已在 India Compliance 16.6.0 和 16.6.2(版本 15 上为 15.30.0 和 15.30.2)中修复。如果你的版本较旧,请更新应用。

“请在公司中设置默认 GST 费用科目……”

Please set Default GST Expense Account in Company Bombay Byte Systems Pvt Ltd

采购发票或收货单中包含无法作为进项税抵扣(不合格 ITC)的 GST,例如第 17(5) 条涵盖的物料。India Compliance 会将这部分 GST 转入费用科目,但需要知道是哪一个科目。

  1. 打开公司。
  2. 将默认 GST 费用科目设置为一个费用明细科目,而不是分组科目。
  3. 重新提交发票。

参见不合格 ITC。

  • 印度 GST、电子发票和电子运单:查找你的答案
  • India Compliance 中的 GST 设置
  • 物料税务模板
  • 多分支机构的 GST

GST API错误:凭证、GSTIN或“API额度已用完”

电子发票、电子运单、GSTR-1、GSTR-2B 以及其他 GST 功能都通过 India
Compliance 应用调用政府 API。当调用因凭据、GSTIN、”API 额度已用尽”或”账户套餐限额
已超出”错误而失败时,原因不外乎下面三种情况之一。本页帮助你判断属于哪一种。

错误信息

Please set the relevant credentials for GSTIN 27AABCB1234D1ZK in GST Settings to use the e-Invoice API
Please enable API in GST Settings to use the e-Waybill API

同一问题的其他提示信息:API credits exhausted、Account plan limit exceeded(GEN5005)、
Invalid login credentials、Invalid username or password、GSTIN is not enabled for e-invoicing。

GST API 的工作原理

要让 API 调用正常工作,必须同时满足以下三个条件:

  1. 站点的 API 访问权限。站点需要一个 API 密钥。在 Frappe Cloud 上,此访问权限已随
    你的站点附带提供,无需购买额度。在自托管站点上,你需要通过
    India Compliance 账户购买额度。
  2. 每个 GSTIN 和每项服务的凭据。在 GST 设置 → 凭据中,每个 GSTIN 都需要为其使用的
    每项服务各有一行记录。不同服务使用不同的登录信息:
    • 电子运单 / 电子发票:你在政府电子发票或电子运单
      门户上创建的 API 用户。这不是你平时使用的门户登录账号。
    • 申报(GSTR-1、GSTR-2A/2B 下载、发票管理系统、采购对账):你平时使用的
      GST 门户用户名,并且已在 GST 门户中开启 API 访问权限。
  3. 该 GSTIN 已在政府门户上为该服务启用,例如电子发票功能。

找到你的情况

Frappe Cloud 上出现”API 额度已用尽”或”账户套餐限额已超出”

你的站点登录了某个 India Compliance 账户。在登录状态下,每次 API 调用都会消耗该
账户的额度,即使在 Frappe Cloud 上也是如此。当账户额度用尽时,调用就会失败。

  1. 在搜索栏中搜索 India Compliance 账户并打开它。
  2. 点击 退出登录,并确认。
  3. 再次尝试该操作。此时站点将使用 Frappe Cloud 附带的 API 访问权限。

已购买的额度不可退款。如果你误购了额度,可以保留该账户以备后用,或
联系 India Compliance 团队。

自托管站点上出现”API 额度已用尽”

自托管站点不附带 API 访问权限。请在 India Compliance 账户页面购买额度。参见
India Compliance 账户。

“请为 GSTIN … 设置相关凭据”

在 GST 设置 → 凭据中,没有该 GSTIN 和该服务对应的记录行。

  1. 前往 GST 设置,打开 凭据选项卡。
  2. 添加一行:公司、GSTIN、服务、用户名、密码。
  3. 当 服务 = 电子运单 / 电子发票时,使用电子发票门户上的 API 用户。当 服务 =
    申报时,使用你的 GST 门户用户名。
  4. 保存,然后重试。

“登录凭据无效”或”用户名或密码无效”

政府门户拒绝了该用户名或密码。ERPNext 只是将其原样传递。

  1. 在电子发票或电子运单门户上,检查该 GSTIN 对应的 API 用户是否存在,并重置其
    密码。请使用 API 用户的密码,而不是你平时的登录密码。
  2. 在 GST 设置 → 凭据中更新密码并保存。
  3. 如果仍然失败,请在门户上检查该 GSTIN 是否已启用电子发票功能。

GSTR-1 上传、GSTR-2B 下载或 IMS 因凭据错误而失败

这些功能使用 申报服务,所需的凭据与电子发票不同。

  1. 在 GST 门户中,为你的登录账号开启 API 访问权限。参见
    采购对账设置。
  2. 在 GST 设置 → 凭据中,添加一行,服务 = 申报,并填写你的 GST 门户
    用户名。
  3. 当 ERPNext 要求输入 OTP 时,输入 GST 门户发送到你注册手机号码的验证码。

“请在 GST 设置中启用 API …”

GST 设置 → 常规中的启用 API 功能处于关闭状态。请将其开启并保存。在自托管站点上,
还需登录一个有额度的 India Compliance 账户。

如果这样仍无法解决

  • 站点被迁移或恢复到新服务器:存储的密码无法用新站点的
    加密密钥读取。请重新在 GST 设置 → 凭据中输入密码。参见迁移站点后的 加密密钥错误。
  • 测试:开启在沙盒模式下使用 API?后,调用会发往政府测试系统,
    其中的单据并非真实单据。请为真实发票关闭此选项。
  • 如果仍然失败,请提交支持工单。附上完整的错误信息和集成请求日志
    (在功能栏中搜索集成请求)。
  • 印度 GST、电子发票和电子运单:查找您的答案
  • GST 设置和凭据
  • 印度合规账户

印度商品及服务税、电子发票和电子运单:找到你的答案

ERPNext 中的 GST、电子发票、电子运单、TDS 和 GST 申报都来自 India Compliance 应用。它的
完整文档位于 docs.indiacompliance.app。
本页列出了支持团队最常收到的问题,并附有简短回答和完整答案的链接。

设置

如何设置 GST? 安装 India Compliance,然后在公司地址上设置 GSTIN,在 GST 设置 → 账户 中设置 GST
账户,并设置税务模板。
GST 设置

如何启用电子发票和电子运单? 在 GST 设置 → 常规 中,启用 启用 API
功能
、启用电子发票 和电子运单选项,然后添加凭据。
GST 设置

GST API 需要付费吗? 在 Frappe Cloud 上,只要站点未登录 India Compliance 账户,API 访问就是包含在内的。在自托管站点上,您需要购买额度。
GST API 错误:凭据、GSTIN、”API 额度已用尽”

一家公司在多个州有 GST 注册? 为每个州添加一个带有其 GSTIN 的地址。
交易会从公司地址中选取 GSTIN。
多分支机构的 GST

HSN 代码和 HSN 验证? 为每个物料设置 HSN/SAC 代码。GST 设置可以要求填写并
检查其长度。GST 设置:HSN 代码

新的 2025 年所得税法 TDS 和 TCS 条款? 更新 India Compliance 以获取新的预扣税
类别,然后在供应商上选择它们。TDS 设置

发票上的 GST

为什么 GST 错误、缺失或差几分钱? 通常是供应地、GST 账户、物料税务
模板设置或舍入问题。为什么我的发票上 GST 错误或缺失?

反向征税(RCM)采购? 在 GST 设置中添加反向征税账户,并将采购
发票标记为反向征税。反向征税

不可抵扣的进项税抵免? India Compliance 会将不可抵扣的 GST 转入公司的 默认 GST
费用账户
。ITC 不可抵扣

出口、SEZ、零税率和免税供应? 在 GST
设置中启用 启用 SEZ / 海外交易,并将客户的 GST 类别设置为海外或 SEZ。
销售交易

预付款上的 GST,以及 ITC 的冲回?
其他 GST 交易

输入服务分销商(ISD)? ISD

电子发票

电子发票显示失败、没有 IRN,或 24 小时后无法取消?
电子发票显示失败、没有 IRN,或无法取消

如何生成或取消电子发票?
生成电子发票

凭据或”API 额度已用尽”错误? GST API 错误

想在没有真实发票的情况下测试? 使用沙盒模式。
沙盒

电子运单

生成、更新 Part B 或车辆、延期、取消,或用于库存调拨和来料加工?
电子运单

生成时出现地址、PIN 码或 HSN 错误?
交易验证

GST 申报

发票在 GSTR-1 中缺失,或总计不匹配?
为什么我的发票在 GSTR-1 中缺失,或为什么总计不匹配?

生成、比较和提交 GSTR-1? GSTR-1

GSTR-3B,以及为什么 GSTR-3B 提交后我无法更改发票? India Compliance 会设置 ITC
申报期,并阻止更改已申报的期间。
GSTR-3B 和 ITC 申报期

将采购发票与 GSTR-2A 和 GSTR-2B 匹配?
采购对账

发票管理系统(IMS)? GST IMS

GSTR-9、GSTR-6 或 GSTR-7? 不由 India Compliance 生成。请使用 GST 报表(GST 销售登记簿、
GST 采购登记簿、GST 余额)作为基础,并在 GST 门户上申报。
GST 报表

更新或迁移站点后的错误

更新 ERPNext 或 India Compliance 后出现 TypeError 或其他错误? 这些应用必须处于匹配的
版本:将两者都更新到同一主版本的最新发布版(例如都为 version-16)。
更新后的错误

迁移站点后出现加密密钥错误? 重新输入 GST 凭据。
迁移站点后的加密密钥错误

  • India Compliance 应用
  • India Compliance 文档

更新后打印失败,提示“’NoneType’ object is not callable”或Jinja错误

突然间,就在 Frappe 更新之后,你一打开打印视图或尝试下载 PDF,所有打印格式(或某个特定格式)就立刻失败了。错误信息会指出行号,但不会说明是哪个格式,所以很难看出该修什么。

错误信息

你会看到以下之一,可能是在打印视图中的对话框里,也可能是在 PDF/下载响应中:

Print Format Error

Error in print format on line 19: 'NoneType' object is not callable

或者是更完整的版本,出现在你从 PDF 下载链接得到的服务器错误页面中:

File "apps/frappe/frappe/templates/print_formats/standard.html", line 19, in top-level template code

{{ render_field(df, doc, no_of_cols) }}

File "env/lib/python3.x/site-packages/jinja2/sandbox.py", line 401, in call

return __context.call(__obj, *args, **kwargs)

TypeError: 'NoneType' object is not callable

...

frappe.exceptions.PrintFormatError: Error in print format on line 19: 'NoneType' object is not callable

一个相关的版本会显示 KeyError 或其他 Jinja 异常,而不是 NoneType,但同样呈现”所有打印格式都挂了”的模式。原因和下面的修复方法是一样的。

为什么会发生这种情况

打印格式是通过 Jinja 渲染的:html 模板通过 Jinja 的沙箱调用 Python 函数并读取文档字段。'NoneType' object is not callable 的意思是 Jinja 试图把某个东西当作函数来调用,但那个东西求值结果是 None——通常是一个空白字段(当 备注 为空时就是 {{ doc.remarks() }}),或者是沙箱无法解析的模板宏。

大多数”更新后所有打印格式都坏了”的报告,都可以追溯到 Frappe Framework 本身的一个短暂回归问题,出在每个内置打印格式和基于 Builder 的打印格式共用的 standard.html 模板中——一次核心改动导致其中一个模板宏在两次发布之间的短暂窗口内返回了 None。Frappe 会很快修复这些问题(几小时到几天内),并以补丁版本的形式发布修复,但在你的站点升级到那个版本之前,每次打印和 PDF 都会以同样的方式失败。同一个模板上已经不止一次发生过这种情况,所以”先更新,看看是否修好了”是一个合理的首选操作,而不是一次性的做法。

如果只有一个打印格式失败,其余的都正常,那原因就在那个格式本身:某个自定义打印格式(或合作伙伴定制过的格式)的 Jinja 或自定义 HTML 调用了某个字段、doctype 方法或打印模板钩子,而某个应用更新将其删除、重命名,或对某些文档留空了。

如何修复

  1. 打开文档,点击打印图标,把 打印格式 切换到另一个(某个内置格式,或 标准)。如果它能正常渲染,问题就出在你之前用的那个格式上——跳到第 4 步。如果所有格式都失败,问题就在 Frappe 本身——继续第 2 步。
  2. 阅读 traceback,确认它与本问题相符,并找出失败的位置。在打印视图中,重新选择失败的格式以查看对话框;从 PDF 下载链接(或附带 PDF 的邮件/报表)中,改为打开完整的服务器错误页面——那里有完整的 traceback。

最后一行会指出异常,对于打印格式相关的错误,还会指出你模板中的行号:

如果失败发生在后台任务中(定时报表、附带 PDF 的邮件)——也就是说没有人能看到对话框——请从 Awesome Bar 打开 错误日志,查找同一时间附近针对同一文档的条目;它带有相同的 traceback。
3. 检查你的应用是否处于匹配的、当前的版本。打开 帮助 → 关于(或在 bench 目录下运行 bench version),对比 已安装应用 列表:Frappe Framework、你的主应用(ERPNext 等)以及任何自定义应用都应处于同一版本线(全部 v15,或全部 v16——不要混用),并且都不应落后于该版本线的最新补丁版本。

如果 Frappe Framework 落后了,请更新它:

bench update

bench --site [site-name] migrate

bench build

bench clear-cache

bench clear-website-cache

即使 bench update 无错误地完成,bench build 和两个清除缓存的命令也很重要——过期的 JS/CSS 构建或缓存的页面可能会继续显示旧的、损坏的行为。在 Frappe Cloud 上,你不需要自己运行这些:公共(共享)bench 会在其每周发布日自动更新;在私有 bench 组上,打开站点仪表板中的 更新 并应用待处理的更新。
4. 如果只有你自己的自定义打印格式失败,请打开它(打印格式 列表,或从打印视图中的 自定义),检查 traceback 指出的那一行。查找某个字段引用——它可能对某些文档是空白的,却被当作函数调用(用 {{ doc.some_field() }} 而不是 {{ doc.some_field }}),或者查找从某个应用更新改变了的模板路径导入的宏。修复模板,或者如果该格式是在更新之前构建的,就基于当前的标准布局重新创建它。

如何预防

  • 让 Frappe Framework 和其他应用保持在同一版本线,并处于该版本线的最新补丁版本——大多数这类故障都会在补丁版本中修复,保持最新就能避免它们。
  • 在任何更新之后,在团队重新开始使用站点之前,用你依赖的每个自定义打印格式各打印一份文档。

如果这样仍无法解决

请提交支持工单,并附上:确切的错误文本、打印格式名称、从 帮助 → 关于 中获取的 Frappe Framework 和应用版本,以及你当时正在打印的文档。如果你有完整的回溯信息(来自服务器错误页面或错误日志),请一并附上——这是支持团队确认该问题属于已知的 Framework 回归问题,还是你自己的打印格式中的问题的最快方式。

  • 打印
  • 在哪里可以找到标准打印格式

设置双重身份验证(v17+)

双重身份验证(2FA)为登录增加了一个额外步骤。用户输入密码后,还必须输入验证码。验证码来自身份验证器应用、短信或电子邮件。

本页介绍版本 17 及更高版本。

1. 启用双重身份验证

  1. 转到系统设置 > 登录选项卡 > 双重身份验证部分。
  2. 勾选启用双重身份验证。
  3. 在双重身份验证方式中,选择以下方式之一:
  • “OTP 应用”:用户从身份验证器应用获取验证码,例如 Google Authenticator、Microsoft Authenticator 或 1Password。验证码每 30 秒更换一次(TOTP)。
  • “短信”:用户通过短信获取验证码。
  • “电子邮件”:用户通过电子邮件获取验证码。
  1. 在OTP 签发方名称中,输入用户在身份验证器应用中看到的名称,例如“My Company ERP”。
  2. 如果选择了“短信”,可以在OTP 短信模板中更改短信内容。使用 {{ otp }} 作为验证码的占位符。
  3. 保存。

2. 设置验证码发送方式

每种方式都需要以下设置之一:

  • OTP 应用和电子邮件:设置一个外发电子邮件账户。使用“OTP 应用”时,首次登录会通过电子邮件发送验证码。用户必须先输入此验证码,才能设置应用。
  • 短信:设置短信设置。如果没有短信网关 URL,则无法保存“短信”方式。

3. 选择使用 2FA 的角色

启用 2FA 时,系统会为“全部”角色开启双重身份验证。届时所有用户都必须输入验证码,包括管理员。

如果只想让部分用户使用 2FA:

  1. 打开角色“全部”,取消勾选双重身份验证。
  2. 打开每个必须使用 2FA 的角色(例如“系统管理员”),勾选双重身份验证。

如果用户的某个或多个角色勾选了双重身份验证,则该用户必须输入验证码。

2FA 不适用于使用 API 密钥和 API 密钥密码的 API 请求。

4. 可选:限制 IP 地址

可以在用户上设置限制 IP,仅允许从特定 IP 地址登录。系统设置中的两个设置控制其与 2FA 的配合方式:

  • 对从受限 IP 地址登录的用户跳过双重身份验证:从受限 IP 地址登录的用户无需输入验证码。
  • 启用双重身份验证时跳过受限 IP 地址检查:用户使用 2FA 时可以从任意 IP 地址登录。也可以在用户表单中为单个用户设置此项。

使用 OTP 应用首次登录

首次登录时,用户在登录界面设置身份验证器应用。

  1. 输入用户名和密码,然后点击登录。
  2. 系统会向您的电子邮件地址发送验证码。在验证码中输入此验证码,然后点击验证。此步骤确保只有该电子邮件地址的所有者才能设置应用。
  3. 登录界面会显示一个二维码。打开身份验证器应用并扫描二维码。如果无法扫描,请在应用中手动添加账户,并输入二维码下方显示的设置密钥。
  4. 应用会显示一个 6 位验证码。在验证码中输入此验证码,然后点击验证。

必须在 5 分钟内完成这些步骤。如果超时,请刷新页面并重新登录。

二维码只显示一次。后续登录时,只需输入身份验证器应用中的验证码。

使用短信或电子邮件登录

  1. 输入用户名和密码,然后点击登录。
  2. 系统会向您的手机号码或电子邮件地址发送验证码。
  3. 在验证码中输入验证码,然后点击验证。

验证码有效期为 5 分钟。

丢失设备或更换新设备

如果用户丢失了手机或想使用其他身份验证器应用,请重置其 OTP 密钥:

  1. 打开用户。
  2. 点击密码 > 重置 OTP 密钥。

系统会向用户发送电子邮件,告知其重置情况。下次登录时,用户需按照“使用 OTP 应用首次登录”中所述重新设置身份验证器应用。

用户也可以在自己的用户表单中重置自己的 OTP 密钥。系统管理员可以为所有用户重置。

从版本 16 升级

  • 设置链接电子邮件和 /qrcode 页面已不存在。旧电子邮件中的设置链接将无法使用。未完成设置的用户将在下次登录时在登录界面完成设置。
  • 设置二维码图片页面过期时间已不存在。
  • 升级会从Home/Barcodes文件夹中删除旧的二维码图片。这些图片包含用户的 OTP 密钥。
  • 已经设置好身份验证器应用的用户无需进行任何操作。
  • 常见问题

    我已设置 OTP 应用,但无法登录

    应用生成的验证码取决于您设备上的时间。请确保您设备上的时间准确并已自动同步。与服务器时间相差超过 30 秒可能导致验证码无效。

    我没有收到包含验证码的邮件

    请确保外发电子邮件账户工作正常,并检查您的垃圾邮件文件夹。如果验证码已过期,请刷新页面并重新登录以获取新的验证码。

    Sentry集成

    Sentry 是一个错误跟踪和性能监控服务。每当发生错误时,应用程序会向它发送一份报告。Sentry 会将相同的错误归并为一个 issue,显示堆栈跟踪和上下文,并在出现新 issue 时提醒团队。你可以使用 sentry.io 上的托管服务,也可以自行部署。借助 Sentry,你可以在一个地方找到所有站点的生产环境错误,而不必逐个搜索每个站点的错误日志。

    概述

    当你设置一个环境变量并且站点选择启用遥测后,Frappe 会将意外的服务器错误和 desk JavaScript 错误发送到 Sentry 项目。可选变量可以添加性能跟踪、性能分析和 SQL span。

    • 每个 bench 一个 DSN。 DSN 来自进程环境,而不是来自 site_config.json。由同一组 web 和 worker 进程服务的所有站点都会报告到同一个 Sentry 项目。
    • 两个开关。 DSN 为进程开启 Sentry SDK。系统设置中的复选框允许发送使用数据以改进应用程序(enable_telemetry)决定每个站点是否发送任何内容。
    • 错误跟随错误日志。 在服务器上,当 Frappe 写入一条错误日志时,事件会发送到 Sentry。如果你看到一条错误日志,Sentry 应该也有。
    • 站点通过名称区分。 每个事件都会将 Sentry 用户 ID 设置为站点名称,因此你可以在 Sentry 中按站点筛选。

    设置

    为 web 和 worker 进程设置 FRAPPE_SENTRY_DSN,重启它们,然后在每个应报告的站点上启用遥测。

    变量 值 效果
    FRAPPE_SENTRY_DSN 你项目的 DSN 必需。在 web 服务器和后台 worker 中启动 Sentry SDK,并在 desk 中加载浏览器 SDK。
    SENTRY_TRACING_SAMPLE_RATE 0.0 到 1.0 之间的浮点数,例如 0.1 可选。为该比例的 web 请求和作业发送性能跟踪。
    SENTRY_PROFILING_SAMPLE_RATE 0.0 到 1.0 之间的浮点数 可选。为该比例的被跟踪事务发送 CPU 性能分析。需要启用跟踪。
    ENABLE_SENTRY_DB_MONITORING 任意非空值,例如 1 可选。将每个 SQL 查询记录为一个 span,并将每次数据库连接记录为一个面包屑。
    1. 在 Sentry 中创建一个项目(平台:Python)并复制其 DSN。
    2. 将这些变量添加到 Frappe web 服务器(gunicorn)以及每个 bench worker 进程的环境中。使用 supervisor 时,使用每个程序的 environment= 行。使用 Docker 时,在后端和 worker 容器上设置它们。
    3. 重启进程。Frappe 仅在进程启动时读取这些变量。
    4. 在每个站点上,打开系统设置并勾选允许发送使用数据以改进应用程序。从 CLI 执行:bench --site <site> execute frappe.db.set_single_value --args "['System Settings', 'enable_telemetry', 1]"</site>。
    5. 在浏览器中重新加载 desk,以便加载浏览器 SDK。

    如果设置了 DSN 但站点的 enable_telemetry 处于关闭状态,该站点不会发送任何内容:没有服务器事件,没有浏览器事件,并且 desk 不会加载 SDK。

    捕获的内容

    Sentry 会获取开发者可以在代码中修复的错误。Frappe 有意向用户显示的错误则被排除在外。

    来源 发送到 Sentry 不发送
    Web 请求 以 HTTP 5xx 结束的未捕获异常。在开发者模式下,Frappe 记录的每个错误。 frappe.ValidationError、frappe.PermissionError 及其子类(例如 frappe.throw() 消息、必填字段错误)。正常的 4xx 响应。
    后台作业 失败并写入错误日志的作业。Worker 在每个作业后刷新事件。 与 web 请求相同的异常过滤器。
    frappe.log_error() 来自应用代码的每次调用,如果有活动异常则作为异常事件,否则作为带有标题和回溯的消息。 错误日志插入本身失败的调用。
    Desk(浏览器) /desk 上的未捕获 JavaScript 错误和未处理的 promise 拒绝。 JS 中由 frappe.throw() 引发的错误。门户和网站页面:SDK 仅在 desk 中加载。会话跟踪已关闭。

    服务器 SDK 运行时关闭了 Sentry 的默认集成。它不会挂钩 Python logging,因此 frappe.logger().error(...) 不会创建 Sentry 事件。来自 CSSUTILS 日志记录器的事件会被丢弃。

    发布版本是 Frappe 版本(服务器上为 frappe.__version__,浏览器中为 frappe.boot.versions.frappe),因此你可以看到是哪个版本引入了错误。

    性能监控

    设置 SENTRY_TRACING_SAMPLE_RATE 以在 Sentry 中查看缓慢的端点和作业。在繁忙的站点上从低值开始(0.01 到 0.1),因为每个被跟踪的请求都会作为事务计费。

    • Web 请求。 Frappe 将 WSGI 应用包装在 Sentry 的中间件中。事务按端点命名:RPC 调用为 /api/method/<dotted.path></dotted.path>,否则为 URL 路径。
    • 后台任务。事务以任务的方法命名。计划任务则使用调度器任务类型。任务上下文包含任务 ID、其参数、是否为计划任务,以及它在队列中的等待时间(秒)。
    • SQL span。启用 ENABLE_SENTRY_DB_MONITORING 后,每次 frappe.db.sql() 调用都会变成一个带有查询文本的 span,并且每次数据库连接都会添加一条面包屑。这就是你查找 N+1 查询的方法。它也会给每次查询增加开销,所以在繁忙的生产环境中启用前请先测量。
    • 性能分析。SENTRY_PROFILING_SAMPLE_RATE 是被追踪事务的一部分,因此 0.5 在追踪率为 0.1 时会分析 5% 的请求。

    当这三个变量中的任意一个被设置时,Frappe 还会在每个请求和任务开始时标记作用域(事务名称、站点、用户、追踪 ID)。这仅在启用了遥测的站点上发生。

    数据与隐私

    错误事件可能包含业务和个人数据。请像对待生产数据库一样对待你的 Sentry 项目,并限制可以读取它的人员。

    Sentry 中的字段 内容
    用户 ID 站点名称,例如 “erp.example.com”
    标签 frappe_user 已登录用户,例如 “jane@example.com”,或 “Guest”
    标签 frappe_trace_id X-Frappe-Request-ID 标头(如果请求带有的话)
    请求 URL、方法、查询字符串和标头。SDK 会剥离 Cookie、Authorization 和其他敏感标头。不包含客户端 IP。
    上下文 “JSON Body” / “Form Data” 完整的请求负载,未经过滤。这可能包含文档数据和个人数据。
    额外 job 任务 ID、方法、所有任务参数、队列等待时间
    堆栈跟踪 带有局部变量的代码帧(Sentry SDK 默认)
    消息 对于 frappe.log_error() 调用:Error Log 标题和回溯
    模块、argv 已安装的 Python 包和进程命令行
    SQL span 仅查询文本。查询值不会被发送。

    遥测复选框不涵盖性能数据。选择性加入检查针对错误事件和作用域标签运行。追踪、性能分析和 SQL span 会为进程中的每个请求和任务启动。如果一个 bench 托管了未选择加入的站点,请不要在其上设置这三个性能变量。

    对于其他你绝不能存储的内容(例如包含国民身份证号或银行详细信息的字段),请使用 Sentry 的服务器端数据擦除功能。

    故障排除

    症状 检查项
    完全没有事件 FRAPPE_SENTRY_DSN 是否在运行进程的环境中,而不仅仅是你的 shell 中?设置后你是否重启了 Web 和工作进程?站点的 enable_telemetry 是否开启?
    存在 Error Log,但 Sentry 中没有任何内容 该异常是否是 ValidationError 或 PermissionError 的子类?这些会被有意跳过。
    Sentry 中有 500 错误,但没有 Error Log 几秒后再检查。请求错误会以延迟插入的方式写入 Error Log。
    缺少任务错误 检查工作进程是否具有 DSN。工作进程在启动时会启动自己的 SDK。
    没有浏览器错误 打开 desk 并检查浏览器控制台中 frappe.boot.sentry_dsn 是否有值。如果为空,则站点的遥测已关闭。Content-Security-Policy 规则必须允许向你的 Sentry 主机发起请求。
    事务过多或 Sentry 账单过高 降低 SENTRY_TRACING_SAMPLE_RATE 或将其移除,然后重启。
    缺少来自脚本或 bench console 的错误 只有 Web 服务器和 bench worker 会启动 SDK。其他 CLI 命令不会向 Sentry 报告。

    代码位于 frappe/utils/sentry.py、frappe/app.py(Web)、frappe/utils/background_jobs.py(工作进程)、frappe/utils/error.py(log_error 钩子)和 frappe/public/js/sentry.bundle.js(浏览器)中。