集成时出错
错误处理对于构建成功的产品集成至关重要。事情并不总是能正常运行,您的目标应该是在这种情况发生时尽可能地减少客户的挫败感。本风格指南旨在使您(开发人员)能够以一种自我服务的方式编写更好的代码,更有效地处理错误,最终减少用户联系技术支持的需要。
免责声明
本指南是围绕使用请求库构建的,尽管这些概念与代码相对不可知。
信任但验证第三方API文档。
错误消息
除非另有说明,所有面向用户的文本应遵循正确的英语语法/拼写/语法,包括错误消息。使用与构建插件所用的产品一致的语言编写错误消息。
如果可能,引导用户找到错误的潜在解决方案,并在他们解决问题后提醒他们测试集成
下面是两个错误消息示例——一个是好的,一个是坏的:
好:错误:对ACME服务的身份验证失败。请验证您在插件连接中配置的API密钥是否正确输入,并且您的ACME服务API键有效,然后重试。如果问题仍然存在,请联系支持。
坏的:无法验证痤疮
“好的”消息之所以好,是因为它详细说明了错误(身份验证),将身份验证凭据标识为问题,提供纠正问题的自助式步骤,并指示用户在需要时联系技术支持。
“不好的”信息之所以不好,是因为它不使用正确的英语,也不提供任何其他信息。这包括没有解释可能导致故障的原因,没有提供补救措施,没有指导用户采取适当的行动。这可能会导致未报告的错误和浪费时间。
的代码
这是一些代码概述,这些代码有效且有效地处理错误,同时显示对用户的有用,人类可读的消息。
action.py
Python
1
进口杰森
2
从…起komand.。例外情况进口插件隔离
3.
4.
def运行(自己那参数={}):
5.
business_object_id=参数[“业务对象id”]
6.
public_id.=参数[“公共标识”]
7.
8.
URL.=自己。连接。base_url()+“/api/V1/getbusinessobject/busobid/{busobid}/publicid/{publicid}”。格式(
9.
布索比德=business_object_id那
10
Puistid.=public_id.
11
)
12
13
响应=自己。连接。会议()。得到(URL.)
14
如果响应。status_code.不在范围(200那299):
15
提高插件隔离(
16
导致=“从Cherwell收到HTTP%d状态代码。请验证您的Cherwell服务器状态,然后重试。”那
17
援助=“如果问题持续存在,请联系技术支持。”那
18
数据=F”{响应。status_code.}那{响应。文本}“
19
)
20.
21
试一试:
22
响应数据=响应。杰森()
23
除了杰森。译码器。JSONDECODEROR:
24
提高插件隔离(
25
导致=“收到Cherwell的意外响应”那
26
援助=“(未收到JSON或响应)。”那
27
数据=响应。文本
28
)
29
30.
返回{“成功”:真正的那“原始响应”:响应数据}
现在,让我们将这个示例分解并检查它。
第1节-状态码检查
Python
1
如果响应。status_code.不在范围(200那299):
2
提高插件隔离(
3.
导致=“从Cherwell收到HTTP%d状态代码。请验证您的Cherwell服务器状态,然后重试。”那
4.
援助=“如果问题持续存在,请联系技术支持。”那
5.
数据=F”{响应。status_code.}{响应。文本}“
6.
)
本节处理响应的HTTP状态代码。可以找到具有它们对应标题和描述的HTTP状态代码的完整列表在这里。
并不是所有的API都使用适当的HTTP状态代码,所以一定要在任何通用列表上使用API文档状态代码。
此代码使用如果语句来验证状态码不在200-299范围内。200代表“OK”。如果状态代码不在这个范围内,那么我们将通过引发a的方式停止集成的执行插件隔离并向用户解释问题所在。
第2节 - 有效载荷验证
Python
1
进口杰森
2
试一试:
3.
响应数据=响应。杰森()
4.
除了杰森。译码器。JSONDECODEROR:
5.
提高插件隔离(
6.
预设=插件隔离。预设。Invalid_json.那
7.
数据=响应。文本
8.
)
本节标记从响应获取JSON有效负载的尝试。如果有效负载不是JSON,或者它根本不存在,那么这个调用将失败并抛出JSONDecodeError。当用户查看日志时,如果不处理此异常,则该异常最终将毫无用处,因为它不包含任何关于响应的信息。
您可以通过通知用户收到的响应处于意外格式,然后打印出响应的文本来处理此操作。这将产生来自服务器的响应,这将为用户提供有关问题的更多信息以及它们如何纠正它。
在可能的情况下,指导用户查阅可能有助于解决其问题的产品文档。以下是一个示例,用于指导用户在提供自定义JSON对象作为插件操作输入时使用文档:
Python
1
提高插件隔离(
2
导致=“Okta:创建用户意外失败。”那
3.
援助=“确保任何提供的对象(例如配置文件或凭据)匹配OKTA模式。”
4.
“更多详情,请参见https://developer.okta.com/docs/api/resources/users#request-parameters”
5.
)
提高异常
作为开发人员,在处理错误时可以采取两种常规操作。
当不需要停止插件代码时,可以记录错误,但继续执行。你可以用self.logger.error(…)向用户提供错误消息。
一种插件隔离将停止插件代码的执行。你可以用它来做这个抛出PluginException(cause="reason", assistance="helpful message")然后向用户提供原因和帮助消息(如上一节所述),以便进行可能的补救。当代码中出现致命或错误场景时,您可以使用此方法——例如接收HTTP 500错误、无效响应、无效身份验证等。
潜在的错误
此列表并不包含所有内容,因此请注意您正在使用的文档。考虑到这一点,遵循这个通用列表并根据需要进行调整,以实现特定的集成,应该会让您(和用户)有一个良好的开端。
- 确保用户输入正确。必要时验证用户输入。
- 检查响应上的HTTP状态代码。使用API文档并处理它们列表的所有方案。根据文档自定义错误消息。如果它们不存在文档,请检查最常见的文档。注意:有些api在发生错误时在响应中提供错误消息。如果是这种情况,请将错误消息返回给用户。
- 检查响应有效负载类型。例如,如果您期望一个JSON响应,但是您得到的是纯文本响应,甚至是XML,那么您的插件代码会崩溃吗?如果是,请处理。Try/except子句在这种情况下非常有效。如果可能的话,向用户提供完整的回复文本。
- 检查是否存在所需数据。我们需要的所有数据都出现在响应中了吗?如果不是,我们可以继续执行吗?或者这是一个致命错误,我们需要提出插件隔离?使用你的判断和可用的文件在这里。
习俗
在可能的情况下对这些进行标准化。
例子
JSondecode.
Python
1
进口杰森
2
从…起komand.。例外情况进口插件隔离
3.
。。。
4.
试一试:
5.
响应数据=响应。杰森()
6.
除了杰森。译码器。JSONDECODEROR:
7.
提高插件隔离(
8.
预设=插件隔离。预设。Invalid_json.那
9.
数据=响应。文本
10
)
连接异常
提供与插件与的连接相关的错误消息connectionTestException.接口。
该接口提供了预设错误消息的列表。这些预设中的每一个都与特定原因和辅助信息相关联。此列表受到频繁更改的影响,因此代码是最佳地点最新名单。
列表中的一些预设错误消息可能包括:
1
API_KEY = " API_KEY”
2
未经授权=“未经授权”
3.
RATE\u LIMIT=“RATE\u LIMIT”
4.
USERNAME_PASSWORD = " USERNAME_PASSWORD "
5.
not_found =“not_found”
6.
server_error =“server_error”
7.
服务不可用=“服务不可用”
8.
INVALID_JSON=“INVALID_JSON”
9.
UNKNOWN=“UNKNOWN”
10
BASE64_ENCODE = " BASE64_ENCODE "
11
base64_decode =“base64_decode”
使用预设的示例用户名和密码:
Python
1
从…起komand.。例外情况进口connectionTestException.
2
。。。
3.
响应=请求。得到(自己。URL.那验证={“用户名”:'blah'那“密码”:'blah')
4.
5.
#https://developer.atlassian.com/cloud/jira/platform/rest/v2/?utm_source=%2fcloud%2fjira%2fplatform%2frest%2f&utm_medium=302#error-responses.
6.
如果响应。status_code.==401.:
7.
提高connectionTestException.(预设=connectionTestException.。预设。用户名和密码)
出现异常时,此示例将返回以下消息:
Komand.Exceptions.loggedException:连接测试失败!提供的用户名或密码无效。验证您的用户名和密码是否正确。
它还包括通过提供导致那援助,数据论据。
Python
1
从…起komand.。例外情况进口connectionTestException.
2
。。。
3.
响应=请求。得到(自己。URL.那验证={“用户名”:'blah'那“密码”:'blah')
4.
如果响应。status_code.==404.:
5.
提高connectionTestException.(
6.
导致=“无法达到JIRA实例:%s。”%自己。URL.那
7.
援助=“验证插件连接中配置的URL处的Jira服务器是否正确。”
8.
)
出现异常时,此示例将返回以下消息:
1
Komand.Exceptions.loggedException:连接测试失败!
2
3.
无法到达Jira实例:https://example.jira.com。验证Jira服务器在你的插件连接中配置的URL是正确的。
另一个例子使用可选数据要追加的参数回答是:在最后。当API提供了有用的消息,或者出现了错误,您希望向用户提供意料之外的响应时,使用这种方法是很好的。
Python
1
进口杰森
2
从…起komand.。例外情况进口connectionTestException.
3.
。。。
4.
试一试:
5.
响应数据=响应。杰森()
6.
除了杰森。译码器。JSONDECODEROR:
7.
提高插件隔离(
8.
预设=插件隔离。预设。Invalid_json.那
9.
数据=响应。文本
10
)
出现异常时,此示例将返回以下消息:
1
komand.exceptions.LoggedException:插件执行时出错!
2
3.
收到来自服务器的意外响应。(非json或没有收到响应)。响应为:{"asdf": asdf}
插件的例外
您可以在连接测试方法的几代内使用相同的机制在连接测试方法之外使用插件隔离. 它也支持相同的预设。
Python
1
从…起komand.。例外情况进口插件隔离
2
味精='用户在给定的时间内发送了太多请求:您已超过此服务的速率限制。'
3.
。。。
4.
提高插件隔离(导致='收到Abuseipdb的错误响应。'那援助='可能的要求太多了。'那数据=味精)
出现异常时,此示例将返回以下消息:
1
Komand.Exceptions.pluginexception:插件执行期间发生错误!
2
3.
从AbuseIPDB收到错误响应。可能有太多的请求。用户在给定的时间内发送了太多请求:您已超过此服务的速率限制。