feathers icon indicating copy to clipboard operation
feathers copied to clipboard

408 timeout error on large objects over sockets

Open dbvcode opened this issue 3 years ago • 3 comments

Steps to reproduce

I get this on a regular basis when I try to upload big objects over socket connection. It is if no data hits the API yet the error appears on the 'before' hook.

I simply call the create method with a big enough object:

await feathersApp.service('historic-data-klines').create(data);

The error is:

 type: 'FeathersError',
  code: 408,
  className: 'timeout',
  data: { timeout: 5000, method: 'create', path: 'historic-data-klines' },
  errors: {},
  hook: {
    type: 'before',
    arguments: [ [Object] ],
    service: {
      events: [Array],
      path: 'historic-data-klines',
      connection: [Socket],
      method: 'emit',
      timeout: 5000,
      ...
    },
    app: Object <[Object: null prototype] {}> {
      ...
    },
    method: 'create',
    path: 'historic-data-klines',
    ...
    }
...

I use socket.io-client, feathers-reactive and @feathersjs/authentication-client

const socket = io(options.feathersIP);
feathersApp
   .configure(feathersSocketIOClient(socket))
   .configure(feathersAuthClient())
   .configure(rx({
        idField: '_id'
   }));

I thought the error is from the feathers client and there was indeed a timeout issue. So I tried something to increase the timeout like so:

feathersApp.service('historic-data-klines').timeout = 500000000;
await feathersApp.service('historic-data-klines').create(data);

This just waits forever and does not do anything as the actual error just gets lost in the background somewhere.

At this point I wanted to avoid any feathers client completely and use sockets.io directly, so I tried:

import * as io from 'socket.io-client';
const socket = io.connect('https://api.address');
socket.emit('create', 'historic-data-klines', data, (error: any, message: any) => {
    if(error){
        console.error(error);
    }
    console.log('Created', message);
});

With small amounts of data the response if good, but with the big ones I get this this error from the emit response

Error: xhr post error
    at XHR.Transport.onError (/home/dbv/tg/node_modules/engine.io-client/lib/transport.js:68:13)
    at Request.<anonymous> (/home/dbv/tg/node_modules/engine.io-client/lib/transports/polling-xhr.js:113:10)
    at Request.Emitter.emit (/home/dbv/tg/node_modules/component-emitter/index.js:145:20)
    at Request.onError (/home/dbv/tg/node_modules/engine.io-client/lib/transports/polling-xhr.js:314:8)
    at Timeout._onTimeout (/home/dbv/tg/node_modules/engine.io-client/lib/transports/polling-xhr.js:261:18)
    at listOnTimeout (internal/timers.js:557:17)
    at processTimers (internal/timers.js:500:7) {
  type: 'TransportError',
  description: 413

Now this something specific and clear and it's the actual error! I think this is the error that I should have gotten in the feathers client in the first place.

After searching around for other people with this issue and their fixes this can be solved by adding to the API maxHttpBufferSize:

app.configure(socketio({maxHttpBufferSize:1e8}));

Now the feathers-client works over websockets as intended, but there are 2 issues:

  1. Error should not have been a timeout and instead the actual error that was generated by the socketio so I can do something about it.

  2. I don't think the error is thrown by the API on the before hook. It seems to happen somewhere in the client to the express/sockets api but does not hit the hooks. a) I've investigated this with feathers profiler and the historic-data-klines service does not get hit at all when the error is thrown. b) I've investigated it with a console.log on the before all hook and historic-data-klines does not get hit.

I think it's not 'true' to say that the 'before' hook is throwing the error as maybe the client or connection transport is! I think it's a good idea to be specific and detailed.

Expected behavior

I expect the feathers client to throw the error from the socket emit function

Actual behavior

What I have just described

System configuration

Nothing fancy or of interest in this scenario

Module versions (especially the part that's not working):

"@feathersjs/authentication": "^4.5.15",
"@feathersjs/authentication-client": "^4.5.15",
"@feathersjs/authentication-local": "^4.5.15",
"@feathersjs/authentication-oauth": "^4.5.15",
"@feathersjs/configuration": "^4.5.15",
"@feathersjs/errors": "^4.5.15",
"@feathersjs/express": "^4.5.15",
"@feathersjs/feathers": "^4.5.15",
"@feathersjs/socketio": "^4.5.15",
"@feathersjs/socketio-client": "^4.5.15",
"@feathersjs/transport-commons": "^4.5.15"

NodeJS version: v14.18.2 Operating System: Linux Browser Version:

React Native Version:

Module Loader:

dbvcode avatar Jul 26 '22 12:07 dbvcode

Thanks for reporting @dbvcode! There are some documentation-related improvements we can make, here. We could also investigate the other issues if you could make a minimal reproduction.

marshallswain avatar Aug 06 '22 06:08 marshallswain

In v5 we removed all our custom socket timeout handling and just defer directly to Socket.io. So it might be worth testing this with the latest prerelease and see what happens. We may still have to improve socket error handling though if the above error doesn't get caught though.

daffl avatar Aug 15 '22 14:08 daffl

Thanks for the replies @marshallswain and @daffl . Unfortunately I have no time in the near future to do any of the above, but I will report back when I get to do it!

dbvcode avatar Aug 22 '22 08:08 dbvcode