Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Target request stream closed prematurely when having async task(s) within onend_request method

I have a need to do an async lookup (based on received payload) within the onend_request event of a custom plugin. The result then needs to be merged to the payload before it's sent to target.

When performing this task asynchronously it results in the following exception:

targetRequest error 1fd2c2c0-a064-11e8-b06b-f7cfbf5bb289 Error [ERR_STREAM_WRITE_AFTER_END]: write after end
 at write_ (_http_outgoing.js:578:17)
    at ClientRequest.write (_http_outgoing.js:573:10)
    at \npm\node_modules\edgemicro\node_modules\microgateway-core\lib\plugins-middleware.js:372:35
    at \npm\node_modules\edgemicro\node_modules\async\lib\async.js:1154:26
    at \npm\node_modules\edgemicro\node_modules\async\lib\async.js:380:13

followed by

\npm\node_modules\edgemicro\node_modules\async\lib\async.js:43
            if (fn === null) throw new Error("Callback was already called.");
Error: Callback was already called.
    at \npm\node_modules\edgemicro\node_modules\async\lib\async.js:43:36

An empty body is sent to the target.

Looking at the plugins-middleware it seems that the method pipes and closes the stream without waiting for all the onend_requests' callbacks.

To reproduce/demonstrate I've attached a simple plugin (a modified "transform-uppercase" sample plugin), which does the transformation asynchronously, and when run should result with the above error.

I have looked into this slightly further and believe keeping the stream open and closing it only after every plugin onend_request responds is a possible solution. Attaching a patch file of changes to the microgateway-core\lib\plugins-middleware.js which make this work.

Any thoughts on the above? Does the change on the microgateway-code makes sense or is there other/better way to make this work.

0 4 1,316
4 REPLIES 4