Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No reconnect on connecton issues #305

Open
maxim-kukushkin opened this issue Feb 11, 2023 · 5 comments
Open

No reconnect on connecton issues #305

maxim-kukushkin opened this issue Feb 11, 2023 · 5 comments

Comments

@maxim-kukushkin
Copy link

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)
@ex0ns
Copy link
Contributor

ex0ns commented Feb 13, 2023

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)

@maxim-kukushkin
Copy link
Author

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
Copy link
Author

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
Copy link
Author

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

@ex0ns
Copy link
Contributor

ex0ns commented Mar 11, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants