roc-lang / basic-webserver

A basic webserver in Roc
https://roc-lang.github.io/basic-webserver/
Universal Permissive License v1.0
76 stars 16 forks source link

Incorrectly resolve http client response status code #74

Open lost22git opened 1 month ago

lost22git commented 1 month ago

code

app [Model, server] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.9.0/taU2jQuBf-wB8EJb0hAkrYLYOGacUU5Y9reiHG45IY4.tar.br" }

import pf.Stdout
import pf.Http exposing [Request, Response]
import pf.Url

Model : {}

server = { init: Task.ok {}, respond }

respond : Request, Model -> Task Response [ServerErr Str]_
respond = \req, _ -> apiProxy req |> Task.mapErr handleErr

AppError : [
    ParamNotFound Str,
    HttpErr Http.Err,
    StdoutErr Stdout.Err,
]

handleErr : AppError -> [ServerErr Str]
handleErr = \e -> ServerErr (Inspect.toStr e)

apiProxy : Request -> Task Response AppError
apiProxy = \req ->
    target =
        req.url
            |> Url.fromStr
            |> Url.queryParams
            |> Dict.get "target"
            |> Task.fromResult
            |> Task.mapErr! \_ -> ParamNotFound "target"

    Stdout.line! "Fetching [$(Http.methodToStr req.method)] $(target)"

    targetRes = { req & url: target, timeout: NoTimeout } |> Http.send!
    dbg targetRes

    Task.ok targetRes

http test report

❯ xh get http://localhost:8000/proxy?target=https://httpbin.org/ip
HTTP/1.1 500 Internal Server Error
Content-Length: 15
Date: Sat, 21 Sep 2024 13:23:03 GMT

Panic detected!

server error report

❯ roc dev proxy_server.roc --linker=legacy
Listening on <http://127.0.0.1:8000>
Fetching [Get] https://httpbin.org/ip
[proxy_server.roc:36] {body: [123, 10, 32, 32, 34, 111, 114, ...], headers: [{name: "date", value: "Sat, 21 Sep 2024 13:23:03 GMT"}, {name: "content-type", value: "application/json"}, {name: "content-length", value: "33"}, {name: "server", value: "gunicorn/19.9.0"}, {name: "access-control-allow-origin", value: "*"}, {name: "access-control-allow-credentials", value: "true"}], status: 0}
thread 'tokio-runtime-worker' panicked at crates/roc_host/src/http_server.rs:91:13:
not yet implemented: invalid status code from Roc: 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'tokio-runtime-worker' panicked at crates/roc_host/src/http_server.rs:112:26:
called `Result::unwrap()` on an `Err` value: JoinError::Panic(Id(18), ...)
lukewilliamboswell commented 1 month ago

We should really provide a nicer error report when the call to roc crashes... because this is cryptic.

I've only spent a couple of minutes looking at this over a coffee break, but it looks like the Http.send which calls http_client::send_req in the host is returning a status code of 0 which is strange.

The status comes from let status = response.status().as_u16(); which is a hyper response... so there must be something strange going on from this point back into roc. Maybe alignment or FFI something isn't right -- I don't think we've tested the http client that much in web server, maybe worth comparing if the implementation has changed from basic-cli much or a copy-paste error. Some dbg!'s should help get to the bottom of this pretty quickly.

I should be able look into this more tomorrow.