8

Does anybody works with koa.js and streams?

Consider this example

const fs = require('fs');
const Koa = require('koa');

const app = new Koa();

app.use(async (ctx) => {
  ctx.body = fs.createReadStream('really-large-file');
});

app.listen(4000);

If user aborts request I'm getting either

  Error: read ECONNRESET
      at _errnoException (util.js:1024:11)
      at TCP.onread (net.js:618:25)

or

  Error: write EPIPE
      at _errnoException (util.js:1024:11)
      at WriteWrap.afterWrite [as oncomplete] (net.js:870:14)

What is the proper way to handle this type of errors?

P.S. I have no errors after request aborts with express

const fs = require('fs');
const express = require('express');

const app = express();

app.get('/', (req, res) => {
  fs.createReadStream('really-large-file').pipe(res);
});

app.listen(4000);

P.P.S. I've tried

app.use(async (ctx) => {
  fs.createReadStream('really-large-file').pipe(ctx.res);
  ctx.respond = false;
});

But it had no effect.

Stepan Kuzmin
  • 1,031
  • 2
  • 11
  • 21

1 Answers1

-2

Use a gloabel error handler. see https://github.com/koajs/koa/wiki/Error-Handling

const fs = require('fs');
const Koa = require('koa');

const app = new Koa();


app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    ctx.status = err.status || 500;
    ctx.body = err.message;
    ctx.app.emit('error', err, ctx);
  }
});

app.use(async (ctx) => {
  ctx.body = await openFile();
});

function openFile(){
  return new Promise((resolve,reject)=>{
    var stream = fs.createReadStream("really-large-file")
    var data
    stream.on("error",err=>reject(err))
    stream.on("data",chunk=>data+=chunk)
    stream.on("end",()=>resolve(data))
  })
}

app.listen(4000);
Holger Will
  • 7,228
  • 1
  • 31
  • 39
  • Unfortunately this handler does not catch ECONNRESET errors. – Stepan Kuzmin Oct 29 '17 at 13:05
  • sorry, i was not paying attention... a (readable)Stream is not awaitable (which you didn't try ;-) ) and so you can not catch errors there. you have to promisify your file loading to get it to work... updated the answer acordingly... – Holger Will Oct 29 '17 at 15:28
  • 5
    The problem with this is that you pass file contents into memory and then resolve it into the response body. This is not how you should implement streaming. I can just read file contents with `readFileSync` and pass it to the body. – Stepan Kuzmin Oct 30 '17 at 08:34
  • By resolving the data only at the end of the read stream... this unstreams a stream – Zach Smith Aug 23 '22 at 09:02