Padrão de Wait-Retry

Em algumas situações, o comportamento de uma fonte de dados não corresponde ao esperado pelo tratamento de código HTTP padrão do Power Query. Os exemplos a seguir mostram como contornar essa situação.

Nesse cenário, você trabalhará com uma API REST que ocasionalmente retorna um código de status 500, indicando um erro interno do servidor. Nesses casos, você pode esperar alguns segundos e tentar novamente, potencialmente algumas vezes antes de desistir.

ManualStatusHandling

Se Web.Contents receber uma resposta de código de status de 500, ela gerará uma DataSource.Error por padrão. Você pode substituir esse comportamento fornecendo uma lista de códigos como um argumento opcional para Web.Contents:

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

Ao especificar os códigos de status dessa forma, o Power Query continuará processando a resposta da Web normalmente. No entanto, o processamento de resposta normal geralmente não é apropriado nesses casos. Você precisará entender que um código de resposta anormal foi recebido e executar uma lógica especial para lidar com ele. Para determinar o código de resposta retornado do serviço Web, você pode acessá-lo do meta registro que acompanha a resposta:

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

Com base em responseCode 200 ou 500, você pode processar o resultado normalmente ou seguir sua lógica de repetição de espera que você criará na próxima seção.

IsRetry

O Power Query tem um cache local que armazena os resultados de chamadas anteriores para Web.Contents. Ao sondar a mesma URL para uma nova resposta ou ao tentar novamente após um status de erro, você precisará garantir que a consulta ignore todos os resultados armazenados em cache. Você pode fazer isso incluindo a opção IsRetry na chamada para a Web.Contents função. Neste exemplo, definiremos IsRetrytrue após a primeira iteração do Value.WaitFor loop.

Value.WaitFor

Value.WaitFor() é uma função auxiliar padrão que geralmente pode ser usada sem modificação. Ele funciona criando uma lista de tentativas de repetição.

producer Argumento

Isso contém a tarefa a ser (possivelmente) repetida. Ele é representado como uma função para que o número de iteração possa ser usado na producer lógica. O comportamento esperado é que producer retornará null se uma repetição for determinada como necessária. Se algo diferente de null for retornado por producer, esse mesmo valor será então retornado por Value.WaitFor.

delay Argumento

Isso contém a lógica a ser executada entre novas tentativas. Ele é representado como uma função para que o número de iteração possa ser usado na delay lógica. O comportamento esperado é que delay retorna uma Duração.

count Argumento (opcional)

Um número máximo de repetições pode ser definido fornecendo um número para o count argumento.

Juntando as peças

O exemplo a seguir mostra como ManualStatusHandling e Value.WaitFor pode ser usado para implementar uma repetição atrasada no caso de uma resposta 500. O tempo de espera entre repetições dobra com cada tentativa, com um máximo de cinco tentativas.

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