Шаблон Wait-Retry

В некоторых ситуациях поведение источника данных не соответствует стандартной обработке HTTP-кодов Power Query, которую ожидают. В приведенных ниже примерах показано, как обойти эту ситуацию.

В этом сценарии вы будете работать с REST API, который иногда возвращает код состояния 500, указывающий на внутреннюю ошибку сервера. В таких случаях можно подождать несколько секунд и повторить попытку, потенциально несколько раз, прежде чем отказаться.

РучнаяОбработкаСтатуса

Если Web.Contents получает ответ с кодом состояния 500, он по умолчанию выбрасывает DataSource.Error. Это поведение можно переопределить, указав список кодов в качестве необязательного аргумента Web.Contents:

response = Web.Contents(url, [ManualStatusHandling={404, 500}])

Указав коды состояния таким образом, Power Query будет продолжать обрабатывать веб-ответ как обычный. Однако обычная обработка откликов часто не подходит в этих случаях. Вам потребуется понять, что был получен ненормальный код отклика и выполнить специальную логику для его обработки. Чтобы определить код ответа, возвращенный веб-службой, вы можете получить доступ к нему из meta записи, которая сопровождает ответ:

responseCode = Value.Metadata(response)[Response.Status]

В зависимости от того, равен ли responseCode 200 или 500, можно обработать результат как обычно, или следовать логике повторных попыток ожидания, которую вы подробно изложите в следующем разделе.

IsRetry

В Power Query есть локальный кэш, в который хранятся результаты предыдущих вызовов web.Contents. При опросе того же URL-адреса для нового ответа или при повторных попытках после состояния ошибки необходимо убедиться, что запрос игнорирует все кэшированные результаты. Это можно сделать, включив IsRetry параметр в вызов Web.Contents функции. В этом примере мы зададим IsRetry в качестве true после первой итерации цикла Value.WaitFor.

Value.WaitFor

Value.WaitFor() является стандартной вспомогательной функцией , которая обычно может использоваться без изменений. Он работает путем создания списка повторных попыток.

producer Аргумент

Это содержит задачу, которую можно (возможно) повторить. Он представлен как функцию, чтобы число итерации можно было использовать в логике producer . Ожидаемое поведение заключается в том, что producer возвращает null, если определяется, что повторная попытка необходима. Если producer возвращает значение, отличное от null, это значение, в свою очередь, возвращается Value.WaitFor.

delay Аргумент

Это включает логику, которую следует выполнять между повторами. Он представлен как функцию, чтобы число итерации можно было использовать в логике delay . Ожидаемое поведение заключается в том, что delay возвращает длительность.

count Аргумент (необязательно)

Максимальное количество повторных попыток можно задать, указав число аргументу count .

Объединение всего вместе

В следующем примере показано, как ManualStatusHandling и Value.WaitFor можно использовать для реализации задержки повторных попыток в случае ответа 500. Время ожидания между повторными попытками удваивается при каждой попытке с максимальной пятью повторными попытками.

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