Skip to content

Instantly share code, notes, and snippets.

@atsapura
Created June 4, 2020 19:26
Show Gist options
  • Save atsapura/a2b8ab9ffc3d04f8b774e6f59e317de3 to your computer and use it in GitHub Desktop.
Save atsapura/a2b8ab9ffc3d04f8b774e6f59e317de3 to your computer and use it in GitHub Desktop.
let (|CosmosException|_|) (ex:exn) =
match ex with
| :? DocumentClientException as ex -> Some ex
| :? AggregateException as ex when (ex.InnerException :? DocumentClientException) ->
ex.InnerException :?> DocumentClientException |> Some
| _ -> None
let (|NotFoundInCosmos|_|) ex =
match ex with
| CosmosException ex when (ex.StatusCode = Nullable HttpStatusCode.NotFound) -> Some ex
| _ -> None
let upsertDocument (documentClient: DocumentClient) (doc: CosmosDocument<'a>) =
async {
let collectionName = getCollectionName<'a>()
let collectionUri = collectionUri collectionName
try
let etagOptions =
match doc.Etag with
| null | "" -> null
| _ -> etagCondition doc
let! response = documentClient.UpsertDocumentAsync(collectionUri, doc, etagOptions) |> Async.AwaitTask
return
match response.StatusCode with
| HttpStatusCode.OK | HttpStatusCode.Accepted | HttpStatusCode.Created -> Ok()
| HttpStatusCode.Forbidden -> CollectionIsFull collectionName |> Result.Error
| HttpStatusCode.RequestEntityTooLarge -> RequestEntityTooLarge |> Result.Error
| unexpected -> failwith <| sprintf "Unexpected response code %A" unexpected
with
| CosmosException ex ->
match ex.StatusCode |> Option.ofNullable |> Option.defaultValue HttpStatusCode.OK with
| HttpStatusCode.PreconditionFailed -> return Result.Error OptimisticConcurrencyFail
| HttpStatusCode.Forbidden -> return CollectionIsFull collectionName |> Result.Error
| HttpStatusCode.RequestEntityTooLarge -> return RequestEntityTooLarge |> Result.Error
| _ -> return (throwCapture ex)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment