Koa: Assertion Error: Headers already sent

Created on 13 Dec 2017  路  11Comments  路  Source: koajs/koa

Code:
https://gist.github.com/haxxorsid/348169a3a6c93ee241dfdb8170709651
Run:

git clone https://gist.github.com/haxxorsid/348169a3a6c93ee241dfdb8170709651.git
cd 348169a3a6c93ee241dfdb8170709651
npm install
npm start

In browser: http://localhost:3000/my-scale/resize/100/123?url=image.jpg
It resizes image.jpg(without overwriting the file) to 100width & 123height and displays that in browser.

Error:
AssertionError [ERR_ASSERTION]: headers have already been sent

Can someone solve this issue for me. Maybe this issue is not at all related to koajs.

question

All 11 comments

Yea, that entire request isn't wrapped in a promise. The promise resolves and Koa returns, then you set status.

Make sure your middleware returns a promise which resolves after you set ctx.status.

@fl0w I didn't understood. I am new to this, can you give me a example code or fix my existing code? I am not able to write the correct solution to this. As you said correctly, the problem is arrising between Line 37 & Line 48 that is related toctx.set and ctx.status.

@haxxorsid I wrote an article describing how Koa middleware works, including an example that covers why your code does not work (and @fl0w gave the correct answer) so I hope it will explain it in more detail for you: https://medium.com/netscape/mastering-koa-middleware-f0af6d327a69

@jeffijoe
Did as you and fl0w said:


router.get('/my-scale/resize/:width/:height?', async(ctx, next) => {
  const protocol = (options.baseHost.startsWith('https')) ? https : http
        let format = 'webp'

        const imageUrl = getImageUrl(options.baseHost, ctx.query.url)

        const width = parseInt(ctx.params.width, 10)
        const height = parseInt(ctx.params.height, 10) || null
        const transformer = transform(width, height).on('error', function sharpError(err) {
                    ctx.status = 500;
                    next(new Error(err))
                })

        const etagBuffer = Buffer.from([imageUrl, width, height, format])
        ctx.set('ETag', etag(etagBuffer, {weak: true}))
        if (ctx.fresh) {
            ctx.status = 304;
            next();
        }
    const request = new Promise(resolve => protocol.get(imageUrl, resolve));
        const result = await request;


        if (result.statusCode >= 400) {
          ctx.status = result.statusCode;
          next();
        }
        ctx.status = result.statusCode;
        const inputFormat = result.headers['content-type'] || ''
        format = format || inputFormat.replace('image/', '')

        format = sharp.format.hasOwnProperty(format) ? format : 'jpeg'

        ctx.type = 'image/' + format
        result.pipe(transformer).pipe(ctx)

});

What is wrong in this? Can you rectify this?

All the places you use next() you need to return next() instead. Please read the article to understand why. 馃槃

@jeffijoe Ok I rectified and updated the gist, but I am receiving a 404 not found. Route is reachable, but still ...any idea?

Condition: result.statusCode >= 400 comes up as true. Any idea why? I have image present in root, still there is some problem in fetching image in function getImageUrl or maybe there is some problem in promise.

@haxxorsid another thing I noticed, https://gist.github.com/haxxorsid/348169a3a6c93ee241dfdb8170709651#file-server-js-L36

You should not pass anything to next(); if you want to throw an error, you should just throw it.

Additionally, I don't think ctx is a Stream, so you might want to pipe to ctx.res instead.

@jeffijoe Ok fixed and updated the gist. I am receiving "OK" on screen. Almost close to complete this...

I expect output to be like this:
image

But I am getting output like this:
1

Actually, instead of result.pipe(transformer).pipe(ctx.res), try ctx.body = result.pipe(transformer)

WORKED!!!

a9ade90862c01733bbd7f56e883eb60b18c899d6119a040bd58609f6ef0a0aad

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rally25rs picture rally25rs  路  4Comments

koalex picture koalex  路  3Comments

felixfbecker picture felixfbecker  路  5Comments

ilkkao picture ilkkao  路  4Comments

tvq picture tvq  路  4Comments