question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Telegraf Crashes When replyWithPhoto Is Used with Webhook

See original GitHub issue

Context

  • Telegraf.js Version: 3.21.2
  • Node.js Version: v10.3.0
  • Operating System: Ubuntu 18.04 LTS

Expected Behavior

I have a simple bot, which replies with image to any text received. Basically, everything it does is

bot.on('text', ctx => {
  ...
  ctx.replyWithPhoto({source: fs.createReadStream(somePath)}, {caption: someCaption})
  ...
})

Everything works just fine when the bot is configured to use polling, but crashes if I set up webhook.

Current Behavior

When I configure the bot to use webhook, it crashes when I try to send a photo with ctx.replyWithPhoto. If I modify the code above to:

bot.on('text', ctx => {
  ...
  ctx.reply(someMessage)
  ctx.replyWithPhoto({source: fs.createReadStream(somePath)}, {caption: someCaption})
  ...
})

everything works. So basically, telegraf crashes when photo is being sent with answerToWebhook.

Failure Information (for bugs)

Failure Logs

telegraf:client HTTP call setWebhook { url:
   'https://HOST/SECRETADDRESS' } +0ms
  telegraf:client Call via webhook sendPhoto { chat_id: 94968010,
  photo:
   { source:
      ReadStream {
        _readableState: [ReadableState],
        readable: true,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        path: '/tmp/tmp-8281XUbvvO3XH1A4.tmp',
        fd: null,
        flags: 'r',
        mode: 438,
        start: undefined,
        end: Infinity,
        autoClose: true,
        pos: undefined,
        bytesRead: 0,
        closed: false } },
  caption: 'test caption' } +3s
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at write_ (_http_outgoing.js:580:17)
    at ServerResponse.write (_http_outgoing.js:575:10)
    at MultipartStream.ondata (_stream_readable.js:672:20)
    at MultipartStream.emit (events.js:182:13)
    at MultipartStream.Readable.read (_stream_readable.js:492:10)
    at flow (_stream_readable.js:920:34)
    at resume_ (_stream_readable.js:902:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
    at ServerResponse.onerror (_stream_readable.js:696:12)
    at ServerResponse.emit (events.js:182:13)
    at writeAfterEndNT (_http_outgoing.js:639:7)
    at process._tickCallback (internal/process/next_tick.js:63:19)

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

5reactions
r2axzcommented, Jun 15, 2018

OK, finally it looks like I found the cause for the issue.

The solution is to simply change the code:

bot.on('text', async (ctx) => {
  ctx.replyWithPhoto({source: fs.createReadStream('/some/existing/image.png')})
})

to:

bot.on('text', async (ctx) => {
  return ctx.replyWithPhoto({source: fs.createReadStream('/some/existing/image.png')})
})

There is a perfectly valid reason for this change, though. The code in webhook.ls expects a Promise. When the Promise is resolved, the response is ended. If return is omitted, no promise to wait is received and the response is ended before the response body is fully written.

Basically, the bug is in my code. However, I do think that there is a documentation issue. If you take a look at the Working with files section from which I copied the code, there is no return in the example there. On the other hand, return is used in other parts of documentation. So the documentation kinda sends mixed messages 😃 I believe it should be clearly stated somewhere in the documentation that using return is a must.

1reaction
r2axzcommented, Jun 14, 2018

There is a complete script, which illustrates the problem:

'use strict';
const fs = require('fs')
const Telegraf = require('telegraf')

const bot = new Telegraf(process.env.BOT_TOKEN, { webhookReply: false })
bot.telegram.setWebhook(WEBHOOK_ADDRESS)

bot.start((ctx) => {
  ctx.reply('Hi!')
})

bot.on('text', async (ctx) => {
  ctx.replyWithPhoto({source: fs.createReadStream('/some/existing/image.png')})
})

bot.startWebhook(WEBHOOK_ADDRESS, null, 5000)

When I send /start everything works just fine. When I send any text, bot crashes with the following output:

events.js:167
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at write_ (_http_outgoing.js:580:17)
    at ServerResponse.write (_http_outgoing.js:575:10)
    at MultipartStream.ondata (_stream_readable.js:672:20)
    at MultipartStream.emit (events.js:182:13)
    at MultipartStream.Readable.read (_stream_readable.js:492:10)
    at flow (_stream_readable.js:920:34)
    at resume_ (_stream_readable.js:902:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
    at writeAfterEndNT (_http_outgoing.js:639:7)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Telegraf Crashes When replyWithPhoto Is Used with Webhook
When I configure the bot to use webhook, it crashes when I try to send a photo with ctx.replyWithPhoto. If I modify the...
Read more >
404 error using Telegraf webhook for a bot - Stack Overflow
I'm trying to make a Telegram bot working, and I'm using Telegraf.js. I've set up a webhook by adding a subdomain to my...
Read more >
Building Telegram Bots.pdf - Open Directory Data Archive
Having a bot is a simple way to facilitate all the things you do daily, using the same kind of simple. Telegram chat...
Read more >
Telegraf shut down after write to influxdb
When I POST a json request to the webhook, it successfully routes through ... However, every time I post a value to telegraf,...
Read more >
Telegraf: Modern Telegram Bot Framework for Node.js
use (bot.webhookCallback('/secret-path')) // Set telegram webhook // npm ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found