Modello di ripetizione dei tentativi di attesa
In alcune situazioni, il comportamento di un'origine dati non corrisponde a quello previsto dalla gestione predefinita del codice HTTP di Power Query. Gli esempi seguenti illustrano come risolvere questa situazione.
In questo scenario si userà un'API REST che occasionalmente restituisce un codice di stato 500, che indica un errore interno del server. In questi casi, è possibile attendere alcuni secondi e riprovare, potenzialmente alcune volte prima di rinunciare.
Se Web.Contents
ottiene una risposta di codice di stato 500, genera un'eccezione DataSource.Error
per impostazione predefinita. È possibile eseguire l'override di questo comportamento fornendo un elenco di codici come argomento facoltativo a Web.Contents
:
response = Web.Contents(url, [ManualStatusHandling={404, 500}])
Specificando i codici di stato in questo modo, Power Query continuerà a elaborare la risposta Web come di consueto. Tuttavia, l'elaborazione normale delle risposte spesso non è appropriata in questi casi. È necessario comprendere che è stato ricevuto un codice di risposta anomalo ed eseguire una logica speciale per gestirlo. Per determinare il codice di risposta restituito dal servizio Web, è possibile accedervi dal meta
record che accompagna la risposta:
responseCode = Value.Metadata(response)[Response.Status]
In base al fatto che responseCode
sia 200 o 500, è possibile elaborare il risultato come di consueto oppure seguire la logica di ripetizione dei tentativi di attesa che verrà descritta nella sezione successiva.
Power Query dispone di una cache locale che archivia i risultati delle chiamate precedenti a Web.Contents. Quando si esegue il polling dello stesso URL per una nuova risposta o quando si ritenta dopo uno stato di errore, è necessario assicurarsi che la query ignori i risultati memorizzati nella cache. A tale scopo, è possibile includere l'opzione IsRetry
nella chiamata alla Web.Contents
funzione . In questo esempio verrà impostato su IsRetry
true
dopo la prima iterazione del Value.WaitFor
ciclo.
Value.WaitFor()
è una funzione helper standard che in genere può essere usata senza alcuna modifica. Funziona creando un elenco di tentativi.
Contiene l'attività da ritentare (possibilmente). Viene rappresentato come funzione in modo che il numero di iterazione possa essere usato nella producer
logica. Il comportamento previsto è che producer
restituirà null
se è necessario un nuovo tentativo. Se un valore diverso null
da viene restituito da producer
, tale valore viene restituito a sua volta da Value.WaitFor
.
Contiene la logica da eseguire tra i tentativi. Viene rappresentato come funzione in modo che il numero di iterazione possa essere usato nella delay
logica. Il comportamento previsto è che delay
restituisce una durata.
È possibile impostare un numero massimo di tentativi fornendo un numero all'argomento count
.
Nell'esempio seguente viene illustrato come ManualStatusHandling
usare e Value.WaitFor
per implementare un nuovo tentativo ritardato in caso di risposta 500. Tempo di attesa tra i tentativi raddoppia con ogni tentativo, con un massimo di cinque tentativi.
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