等待重试模式
在某些情况下,数据源的行为与 Power Query 的默认 HTTP 代码处理预期不一致。 以下示例演示如何解决此问题。
在此方案中,你要使用的 REST API 有时会返回 500 状态代码,表示内部服务器出错。 在这些情况下,可以等待几秒钟并重试,在放弃之前可能会重试几次。
如果 Web.Contents
获取 500 状态代码响应,则默认会引发 DataSource.Error
。 可以通过提供代码列表作为 Web.Contents
的可选参数来替代此行为:
response = Web.Contents(url, [ManualStatusHandling={404, 500}])
通过这种方式指定状态代码,Power Query 将继续像往常一样处理 Web 响应。 但是,在这些情况下,正常响应处理通常并不合适。 需要了解是否收到了异常响应代码,并执行特殊逻辑进行处理。 若要确定从 Web 服务返回的响应代码,可以从响应附带的 meta
记录中获取:
responseCode = Value.Metadata(response)[Response.Status]
根据 responseCode
是 200 还是 500,可以按正常方式处理结果,也可以按照等待重试逻辑进行操作,这一点将在下一部分详细阐述。
Power Query 有一个本地缓存,可以存储之前调用 Web.Contents 的结果。 轮询相同 URL 以获取新响应时,或者在错误状态后重试时,需要确保查询忽略任何缓存结果。 为此,你可以在 Web.Contents
函数调用中加入 IsRetry
选项。 在此示例中,我们将在 Value.WaitFor
循环的第一次迭代之后将 IsRetry
设置为 true
。
Value.WaitFor()
是一个标准帮助程序函数,通常无需修改即可使用。 其工作原理是生成重试尝试列表。
这包含(可能)要重试的任务。 它表示为函数,以便可以在 producer
逻辑中使用迭代号。 如果确定有必要重试,则预期 producer
将返回 null
。 如果 producer
返回的不是 null
,则该值将由 Value.WaitFor
返回。
该参数包含在两次重试之间执行的逻辑。 它表示为函数,以便可以在 delay
逻辑中使用迭代号。 预期 delay
会返回“持续时间”。
可以通过向 count
参数提供一个数字来设置最大重试次数。
以下示例展示了在出现 500 响应时,如何使用 ManualStatusHandling
和 Value.WaitFor
实现延迟重试。 每次重试之间的等待时间加倍,最多可重试五次。
let
waitForResult = Value.WaitFor(
(iteration) =>
let
result = Web.Contents(url, [ManualStatusHandling = {500}, IsRetry = iteration > 0]),
status = Value.Metadata(result)[Response.Status],
actualResult = if status = 500 then null else result
in
actualResult,
(iteration) => #duration(0, 0, 0, Number.Power(2, iteration)),
5)
in
if waitForResult = null then
error "Value.WaitFor() Failed after multiple retry attempts"
else
waitForResult