Natalie Perret
Natalie Perret

Reputation: 8997

F# async function containing while loop with async calls fail to compile

Not really sure why my code fails to compile, the error I am having: Incomplete structured construct at or before this point in expression

let resendErrorsAsync (bus: IBus) (errorQueueName: string) =
async {
    let! errorQueue = bus.Advanced.QueueDeclareAsync(errorQueueName) |> Async.AwaitTask
    let! message = bus.Advanced.GetMessageAsync(errorQueue) |> Async.AwaitTask
    while message <> null do
        let utf8Body = Encoding.UTF8.GetString(message.Body)
        let error = JsonConvert.DeserializeObject<Error>(utf8Body)
        let errorBodyBytes = Encoding.UTF8.GetBytes(error.Message)
        let! exchange = bus.Advanced.ExchangeDeclareAsync(error.Exchange, "topic") |> Async.AwaitTask
        let! message = bus.Advanced.GetMessageAsync(errorQueue) |> Async.AwaitTask
}

It seems to be related to my two async calls in the while loop, not really sure why though.

Upvotes: 1

Views: 169

Answers (1)

Tarmil
Tarmil

Reputation: 11362

You can't end a block with a let!, there has to be a body after it; that's the reason for the syntax error.

The message you're defining on the last line is a different variable to the one tested in the while condition. It seems you want to mutate the message; for that, you have to explicitly create a mutable variable:

let resendErrorsAsync (bus: IBus) (errorQueueName: string) =
    async {
        let! errorQueue = bus.Advanced.QueueDeclareAsync(errorQueueName) |> Async.AwaitTask
        let! msg = bus.Advanced.GetMessageAsync(errorQueue) |> Async.AwaitTask
        let mutable message = msg
        while message <> null do
            let utf8Body = Encoding.UTF8.GetString(message.Body)
            let error = JsonConvert.DeserializeObject<Error>(utf8Body)
            let errorBodyBytes = Encoding.UTF8.GetBytes(error.Message)
            let! exchange = bus.Advanced.ExchangeDeclareAsync(error.Exchange, "topic") |> Async.AwaitTask
            let! msg = bus.Advanced.GetMessageAsync(errorQueue) |> Async.AwaitTask
            message <- msg
    }

Upvotes: 4

Related Questions