telegram icon indicating copy to clipboard operation
telegram copied to clipboard

No reconnect on connecton issues

Open maxim-kukushkin opened this issue 2 years ago • 5 comments

I tried to start my bot when the Internet connection was absent and it (obviously) failed with java.net.UnknownHostException: api.telegram.org exception (the full stack trace is below).

The issue is that it hasn't tried to reconnect after that and there seem to be no examples or docs about how to handle connection exceptions and may be kick off a reconnect from the code.

Is it possible to detect it in the current version of the code? If not, can either automatic reconnects, or error callbacks, or examples (if it's already there) be added?

2023-02-10 13:25:09.009 ERROR ScalajHttpClient:39 - RESPONSE XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX {}
java.net.UnknownHostException: api.telegram.org
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:607)
        at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:293)
        at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
        at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)
        at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:203)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1207)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1056)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:189)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1572)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1500)
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:352)
        at scalaj.http.HttpRequest.doConnection(Http.scala:367)
        at scalaj.http.HttpRequest.exec(Http.scala:343)
        at scalaj.http.HttpRequest.asString(Http.scala:492)
        at com.bot4s.telegram.clients.ScalajHttpClient.$anonfun$sendRequest$12(ScalajHttpClient.scala:104)
        at scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$1$$anon$2.block(ExecutionContextImpl.scala:59)
        at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3313)
        at scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$1.blockOn(ExecutionContextImpl.scala:70)
        at scala.concurrent.BatchingExecutor$AsyncBatch.blockOn(BatchingExecutor.scala:202)
        at scala.concurrent.package$.blocking(package.scala:124)
        at com.bot4s.telegram.clients.ScalajHttpClient.$anonfun$sendRequest$11(ScalajHttpClient.scala:105)
        at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:661)
        at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:430)
        at scala.concurrent.BatchingExecutor$AbstractBatch.runN(BatchingExecutor.scala:134)
        at scala.concurrent.BatchingExecutor$AsyncBatch.apply(BatchingExecutor.scala:163)
        at scala.concurrent.BatchingExecutor$AsyncBatch.apply(BatchingExecutor.scala:146)
        at scala.concurrent.BlockContext$.usingBlockContext(BlockContext.scala:107)
        at scala.concurrent.BatchingExecutor$AsyncBatch.run(BatchingExecutor.scala:154)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)

maxim-kukushkin avatar Feb 11 '23 19:02 maxim-kukushkin

Could you share the code that you are using ? It would help me give you some pointers on how to deal with this exception, there is indeed nothing in the doc about that but that could be handled pretty much the same way any exception would (we won't retry inside the library as it is decision that need to be made by the user and needs might be pretty different for all of us)

ex0ns avatar Feb 13 '23 10:02 ex0ns

Essentially it's this:

class MyBot(token: String, chatId: Long, processor: CommunicationProcessor) extends TelegramBot with Polling {
  override val client: RequestHandler[Future] = new ScalajHttpClient(token)

  override def receiveMessage(msg: Message): Future[Unit] =
    if (msg.source != chatId) {
      println(s"Received a message from a wrong chat: id=${msg.source}, title=${msg.chat.title.getOrElse("N/A")}")
      Future.successful(())
    } else
      msg.text match {
        case Some(text) =>
          println(s"Incoming message: source=telegram, msg=$text")
          Future(processor.process(text))
        case None =>
          Future.successful(())
      }
}

And then in Main:

    val bot = new MyBot(config.telegramToken, config.telegramMainChatId, processor)
    val eol = bot.run()

    scala.sys.addShutdownHook {
      bot.shutdown()
    }

maxim-kukushkin avatar Feb 14 '23 13:02 maxim-kukushkin

we won't retry inside the library as it is decision that need to be made by the user and needs might be pretty different for all of us

Yeah, that's true, but it might be quite common use, so maybe it can be set as an input parameter when constructing the instance? Like, no reconnects by default, but the caller can also indicate the reconnects are needed (probably a specific interval or some backoff)

maxim-kukushkin avatar Feb 14 '23 16:02 maxim-kukushkin

@ex0ns, do you by any chance have any thoughts regarding the above?

maxim-kukushkin avatar Mar 10 '23 01:03 maxim-kukushkin

Hello

Sorry I don't have a proper solution as of now (one that I'm liking anyway), and I'm pretty busy, I would definitely encourage you to propose an implementation if you feel like it, otherwise it might have to wait on my side and I might tackle it when I have more room for it

ex0ns avatar Mar 11 '23 08:03 ex0ns