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 71 forks source link

HttpErrorEffect stop the server and result with "Cannot read property 'response' of undefined" #384

Closed carere closed 2 years ago

carere commented 2 years ago

First of all, thx for this awesome package, i was looking for a small web framework (smaller than nest πŸ˜…), and i found yours !!

Describe the bug As the title said, when i use error effect when configuring the server, it result with an error in case of an route not found.

[
  @marblejs/core error:

  🚨  An unexpected error "Cannot read property 'response' of undefined" occured while sending a response. Please check your output/error effect.

  ] {
  name: 'CoreError'
}

To Reproduce All you need to do is to call http://127.0.0.1:1337/foo with the following script

import { createServer, httpListener, HttpStatus, r } from "@marblejs/http";
import { logger$ } from "@marblejs/middleware-logger";
import { map, mapTo } from "rxjs";
import { bodyParser$ } from "@marblejs/middleware-body";

const api$ = r.pipe(
  r.matchPath("/"),
  r.matchType("GET"),
  r.useEffect((req$) => req$.pipe(mapTo({ body: "Hello, world!" })))
);

const error$ = (req$) =>
  req$.pipe(
    map((_) => {
      return {
        status: HttpStatus.BAD_REQUEST,
        body: "Even when i don't use the error param, it's not working ",
      };
    })
  );

const server = createServer({
  port: 1337,
  hostname: "127.0.0.1",
  listener: httpListener({
    middlewares: [logger$(), bodyParser$()],
    effects: [api$],
    error$,
  }),
});

const main = async () => await (await server)();
main();

Expected behavior I think it should work as expected when using specific error effect πŸ˜„

Desktop (please complete the following information):

Additional context I using MarbeJS with ReScript πŸ˜„ . Since, i'm a big lover of RxJS, i would like to promote your framework in rescript community !!

JozefFlakus commented 2 years ago

With the latest version v4 the interface for HttpErrorEffect changed:

Observable<{ error, request }>
  -> Observable<{ status, body, headers, request }>

You didn't get the error because there is missing type assertion of HttpErrorEffect interface to error$: which means:

const error$: HttpErrorEffect = req$ =>
  req$.pipe(
    map(({ request }) => ({
      request,
      status: HttpStatus.BAD_REQUEST,
      body: 'Something'
    }))
  );

I noticed that documentation still uses old interface. Applied a fix πŸ’ͺ

carere commented 2 years ago

Ok thx for the answer, i understand now πŸ˜‰