marblejs / marble

Marble.js - functional reactive Node.js framework for building server-side applications, based on TypeScript and RxJS.
https://marblejs.com
MIT License
2.15k stars 69 forks source link

fp-ts-rxjs bindings with requestValidator$ #327

Closed field123 closed 2 years ago

field123 commented 3 years ago

Describe the bug I'm using fp-ts-rxjs bindings https://github.com/gcanti/fp-ts-rxjs inside a marble effect using the fp-ts pipe.

export const hasuraActions$ = r.pipe(
    r.matchPath('/keycloak'),
    r.matchType('POST'),
    r.useEffect((req$) => pipe(
        req$,
        requestValidator$({body: HasuraKeycloakAction}),
        OB.map(() => ({
            body: {
                name: 'Tester McTesterson',
                email: 't.mct@test.com'
            }
        })),
        )
    ));

When I call the endpoint with an invalid body I get a validation error as expected but when I call it with a valid body I get the marble error bellow and my whole server crashes:

setTimeout(function () { throw err; }, 0); ^

[
  @marblejs/core error:

  🚨  An effect returned a response: "{"body":{"name":"Tester McTesterson","email":"t.mct@test.com"}}" without bound request

  ] {
  name: 'CoreError'
}

If i change up the code to match the docs and use the standard rxjs pipe operator it does whats expected

export const hasuraActions$ = r.pipe(
    r.matchPath('/keycloak'),
    r.matchType('POST'),
    r.useEffect((req$) => req$.pipe(
        requestValidator$({body: HasuraKeycloakAction}),
        map(_ => ({
            body: {
                name: 'Tester McTesterson',
                email: 't.mct@test.com'
            }
        }))
        )
    ));

There clearly somthing I'm not understanding about what's happing in the requestValidator$ as all the types seem to line up with my original example but still cause the error.

Any insight anyone can offer would be great?

I don't know if this is the correct place to ask a question, is there a better place for discussion on marblejs e.g. slack?

Expected behavior To match the behaviour when used within the rxjs pipe.

JozefFlakus commented 3 years ago

Hi @field123!

That is not a but bug an actual design decision. Please read the code part mentioned below: https://github.com/marblejs/marble/blob/master/packages/core/src/http/router/http.router.helpers.ts#L15

Marble.js since version 3.0 can use so called - continuous mode.

Marble.js route resolving mechanism can work in two modes — continuous and non-continuous. The second way is the default one which applies to 99% of possible use cases that you can model with REST APIs. Under the hood, it applies a default error handling for each incoming request making the request processing safe but tangled to disposable stream. [...] The new continuous mode allows you process the stream of incoming requests in a fluent, non-detached way.

It means that with non-continuous mode the Observable<HttpRequest> pipe method is decorated with a mentioned decorateEffect which makes a disposable stream with an error handling - for the sake of simplicity and developer ease of use. By using an fp-ts pipe on req$ you simply get rid of this feature, which means that you have to apply your own catching mechanism.

I don't know if this is the correct place to ask a question, is there a better place for discussion on marblejs e.g. slack?

There is a better place - github.com/marblejs/marble/discussions 🙃