Http-in node & payload too large

Hi There!

I'm using a http-in node to post data to my flow. Sometime when I post somethin that is larger than apiMaxLength (i.e. 5mb), I get a PayloadTooLarge error in the console of Node-RED.

i.e. my node-red docker console:

rednode-nrin_1  | PayloadTooLargeError: request entity too large
rednode-nrin_1  |     at readStream (/usr/src/node-red/node_modules/raw-body/index.js:156:17)
rednode-nrin_1  |     at getRawBody (/usr/src/node-red/node_modules/raw-body/index.js:109:12)
rednode-nrin_1  |     at read (/usr/src/node-red/node_modules/body-parser/lib/read.js:79:3)
rednode-nrin_1  |     at urlencodedParser (/usr/src/node-red/node_modules/body-parser/lib/types/urlencoded.js:116:5)
rednode-nrin_1  |     at Layer.handle [as handle_request] (/usr/src/node-red/node_modules/express/lib/router/layer.js:95:5)
rednode-nrin_1  |     at trim_prefix (/usr/src/node-red/node_modules/express/lib/router/index.js:328:13)
rednode-nrin_1  |     at /usr/src/node-red/node_modules/express/lib/router/index.js:286:9
rednode-nrin_1  |     at Function.process_params (/usr/src/node-red/node_modules/express/lib/router/index.js:346:12)
rednode-nrin_1  |     at next (/usr/src/node-red/node_modules/express/lib/router/index.js:280:10)
rednode-nrin_1  |     at jsonParser (/usr/src/node-red/node_modules/body-parser/lib/types/json.js:119:7)

What I would like to get instead is an exception in the flow that I can capture with the catch node and deal with in the flow. Something like this:

But that catch does not capture anything unfortunately. I am blissfully unaware that the post http-in node failed with 413 payload too large.

Is there a fix for this?

Cheers!

What is the return code in returned msg?

I think you will find the error is not thrown in the endpoint. So the catch can not see it, I think node-reds http server is returning the request as to big.
@dceejay 413, as stated in OG post

Exactly, the frontend code in the screenshot.html file is this:

        $.ajax({
          type: "POST",
          url: "/screenshot",
          dataType: "image/svg+xml;charset=utf-8",
          data: {
            ...data,
            d: svgdata
          },
          complete: (obj) => {
            switch( obj.status ) {
            case 413:
              // apiMaxLength in the settings.js is set to 5mb by default,
              // if svg larger than that, need to increase the limit.
              // Provide a hint to that setting in the error message.
              RED.notify(
                "Screenshot too large, increase apiMaxLength in settings.js.", {
                  type: "error"
                }
              );
              break;
.... snippet ....

and that's where I'm getting the 413 - the http-in node produces nothing. I've got a debug node after it and there is no output.

The size error is thrown by express middleware long before it gets to the http-in handler.

There is no way to get notified of this error in the flow.

Is that a bug or a feature? If I setup an http-in and it generates such an error, should I be informed or not? If I control the code that is using the http-in endpoint (as in this case), I notice it. If OTOH its third party software and I don't regularly check the Node-RED console log, I would remain blissfully unaware of any error.

I would argue that since the fix is increasing the apiMaxLength setting, this error should be noticeable on the flow side since the fix is on the flow side. So that error should be caught and passed up to the flow as an exception IMHO.

That does not seem like an unreasonable request. Let's see what other folk think.

Note: while more of a new feature than a bug fix, my expectation would be - should this be implemented, it would be in the next major version.

1 Like

Cheers! :+1: Should I create an github issue for it?

I think from an end-user perspective, it's too much to require me to know that too, i.e., Node-RED uses an express middleware for its http-in and it could also generate errors. As an end-user I should be informed about any component Node-RED depends on that fails or Node-RED should take care of the failure for me. Else I can just use expressjs directly!

True but I think that should change so that it does hit the flow for the reasoning above!

Yes please. And if you have the capacity to contribute, please branch from (and target your PR to) the dev branch.

A gentle note, to manage expectations: while I am not against this, it is not a given that it will be accepted (and that would be for good reason of course) tho it seems like a desirable feature request.

Fair enough, and I would not approach this if the idea would not be acceptable to the developer team, hence I wish to have the discussion before the development (disc b4 dev!) :+1:

1 Like

Just to summaries our discussion on Slack:

The http-in node adds itself to the middleware so the error might happen in the first usage or the second if there is a http-in involved in the flow.

The issue remains that the body-parser consumes the error*. Secondly the association to the node that caused the error is not explicit therefore its difficult to generate a debug entry in the debug panel. If anything, it would be a case of having a log window with the same output as the console window in which Node-RED was started.

*=it consumes the error but it also passes it along to the middleware chain using http-errors and a call to next(createError(...))

As there doesn't seem to be an elegant solution to this, IMO there is no real point in creating an issue that will simply remain open (except perhaps to point to this discussion).

In the HTTP-IN node, the routes are setup (and their middlewares) dynamically, at runtime, in the HTTP-IN node. It may be feasible to wrap the bodyparser (and catch any errors inside the HTTP-IN node) before adding it to the route and therefore would be in the right context to raise an error from the actual HTTP-IN node.

Can you link to the discussion please?

Yep - discussion starts here Slack

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.