gpt4 book ai didi

error-handling - 在管理错误的同时在管道中链接 REST 调用

转载 作者:行者123 更新时间:2023-12-03 07:46:34 24 4
gpt4 key购买 nike

来自 nodejs,我可以使用 Promises and then operator 链接异步事件我正在尝试探索在惯用的 F# 中是如何完成的。

我试图链接的调用是对某个实体的 HTTP 休息调用,从创建到更新再到上传图像到发布。

函数组合说一个函数的输出应该与要组合的第二个函数的输入相匹配,在我的例子中,公共(public)输入和输出将是 string ,即 JSON 序列化字符串作为所有这些函数的输入和输出。

我了解到您可以使用 >> 组合函数运算符(operator)。理想情况下,函数不应该抛出错误,但是 IO 会发生一些事情,例如在这种情况下,如果我试图创建的实体的 id 存在等等。

未知的问题是如果在链接序列期间发生错误会发生什么,调用者如何知道错误以及描述消息?操作可能在链序列的中间或接近尾端或右端失败。

我对这些函数的期望是在出错时停止执行链并将错误消息返回给调用者。错误消息也是 JSON string所以你知道函数的输入和输出之间没有不兼容。

我看了Choice也是,但不确定这是否是我应该去的方向。

代码不一定完整,我正在寻找的只是进一步研究以获得答案并可能改进这个问题的方向。这是一些开始的代码。

let create schema =
// POST request
"""{"id": 1, "title": "title 1"}""" // result output

let update schema =
// PUT request, update title
"""{"id": 1, "title": "title 2"}""" // output

let upload schema =
// PUT request, upload image and add thumbnail to json
"""{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""

let publish schema =
// PUT request, publish the entity, add url for the entity
if response.StatusCode <> HttpStatusCode.OK then
"""{"code": "100", "message": "file size above limit"}"""
else
"""{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""

let chain = create >> update >> upload >> publish

编辑 - 尝试

尝试在上传部分参数化图像缩略图
let create (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 1"}""" // result output

let update (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 2"}""" // output

let upload2 (img: string) (schema: string) : Result<string,string> =
printf "upload image %s\n" img
let statusCode = HttpStatusCode.OK
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""
| x -> Error (sprintf "%A happened" x)

let publish (schema: string) =
let statusCode = HttpStatusCode.InternalServerError
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""
| _ -> Error """{"code": "100", "message": "couldn't publish, file size above limit"}"""

let chain = create >> Result.bind update >> Result.bind (upload2 "image.jpg") >> Result.bind publish

最佳答案

解决此问题的一个很好的通用方法是将函数的返回值包装在类似 Choice/Either 的类型中,并使用高阶函数将它们绑定(bind)在一起,以便故障传播/短路一些有意义的数据。 F# 有一个 Result输入 bind可以像这样使用的函数:

type MyResult = Result<string,string>
let f1 x : MyResult = printfn "%s" x; Ok "yep"
let f2 x : MyResult = printfn "%s" x; Ok "yep!"
let f3 x : MyResult = printfn "%s" x; Error "nope :("
let fAll = f1 >> Result.bind f2 >> Result.bind f3

> fAll "howdy";;
howdy
yep
yep!
[<Struct>]
val it : Result<string,string> = Error "nope :("

前两个函数成功,但第三个函数失败,所以你得到 Error值回来。

另请查看 Railway-oriented programming 上的这篇文章.

更新 更具体到你的例子:
let create (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 1"}""" // result output
let update (schema: string) : Result<string,string> =
Ok """{"id": 1, "title": "title 2"}""" // output
let upload (schema: string) =
let statusCode = HttpStatusCode.OK
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg"}"""
| x -> Error (sprintf "%A happened" x)
let publish (schema: string) =
let statusCode = HttpStatusCode.InternalServerError
match statusCode with
| HttpStatusCode.OK -> Ok """{"id": 1, "title": "title 2", "thumbnail": "image.jpg", "url": "http://example.com/1"}"""
| _ -> Error """{"code": "100", "message": "file size above limit"}"""
let chain =
create >> Result.bind update >> Result.bind upload >> Result.bind publish

关于error-handling - 在管理错误的同时在管道中链接 REST 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49226552/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com