Try/Catch does not prevent crash

2.3k views Asked by At

I am writing a very simple telegram-bot using the telegraf bot framework. So far it replies to some simple commands using .hears and .on methods, everything works fine so far.

Now I implemented another .hears method which is waiting for the string Miez. Once it "hears" this string it is supposed to .replyWithDocument containing a cat-api url. The URL according to cat-api provides a random cat-gif on every call. So far my code:

const Telegraf = require('telegraf')

const app = new Telegraf('<MY_TOKEN>')

// Connect/Express.js integration
const express = require('express')
const expressApp = express()

expressApp.set('port', (process.env.PORT || 5000));


app.command('start', (ctx) => {
  console.log('start', ctx.from)
  ctx.reply('Welcome!')
})

app.hears('Hi', (ctx) => ctx.reply('Hallo!'))
app.hears('Marco', (ctx) => ctx.reply('Polo'))
app.on('sticker', (ctx) => ctx.reply('❤'))

app.hears('Miez',(ctx) => {
    try{
          return ctx.replyWithDocument({
            url: 'http://thecatapi.com/api/images/get?format=src&type=gif',
            filename: 'cat.gif'
          })

       }catch(error){
            return ctx.reply("Miau");
       }
})

So as you can see I wraped the .replyWithDocument in a try/catch block. I did this because the given url does not always provide a gif. Sometimes you just get a Server not found message. I am hosting the bot on Heroku and here are the logs for the corresponding error:

Failed to process updates. { FetchError: request to http://30.media.tumblr.com/tumblr_lu65p0QXgW1r4xjo2o1_r1_500.gif failed, reason: getaddrinfo ENOTFOUND 30.media.tumblr.com 30.media.tumblr.com:80
    at ClientRequest.<anonymous> (/app/node_modules/telegraf/node_modules/node-fetch/index.js:133:11)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:188:7)
    at Socket.socketErrorListener (_http_client.js:310:9)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at connectErrorNT (net.js:1022:8)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
  message: 'request to http://30.media.tumblr.com/tumblr_lu65p0QXgW1r4xjo2o1_r1_500.gif failed, reason: getaddrinfo ENOTFOUND 30.media.tumblr.com 30.media.tumblr.com:80',
  name: 'FetchError',
  errno: 'ENOTFOUND',
  type: 'system',
  code: 'ENOTFOUND' }

After this is thrown, the bot stops working on Heroku for a while and then comes back up again after 15 minutes or something, I guess it gets restarted after some time of inactivity.

Well, at the bottom line I do not mind the url-call to fail sometimes. What I do not understand is why my try/catch-block is not catching this behaviour. In case my interpretation of the logs is correct.

Edit: A possible reason came to my head, maybe .replyWithDocument is a asynchronous call. So the HTTP-request is successful and the try is too. But once the response is Server not found the method call still fails. If this might be the reason, how would one handle it?

1

There are 1 answers

0
Leonel Atencio On BEST ANSWER

You need to use Telegraf custom error handling methods!.

By default Telegraf will print all errors to stderr and rethrow error. To perform custom error-handling logic use following snippet:

const app = new Telegraf(process.env.BOT_TOKEN)
app.catch((err) => {
  console.log('Ooops', err)
})

Try using above code to catch your 'ENOTFOUND' error.

Source: http://telegraf.js.org/introduction.html#error-handling