diff --git a/gradle.properties b/gradle.properties index 1d02577..1e4944c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ MORNY_ARCHIVE_NAME = morny-coeur MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s -VERSION = 1.3.0-dev8 +VERSION = 1.3.0-dev9 USE_DELTA = false VERSION_DELTA = diff --git a/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala b/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala index f88d9b4..3f3f2d4 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala @@ -99,6 +99,14 @@ class MornyCoeur (using val config: MornyConfig) { import com.pengrad.telegrambot.TelegramException account.setUpdatesListener(eventManager, (e: TelegramException) => { + // This function intended to catch exceptions on update + // fetching controlled by Telegram API Client. So that + // it won't be directly printed to STDOUT without Morny's + // logger. And it can be reported when needed. + // TelegramException can either contains a caused that infers + // a lower level client exception (network err or others); + // nor contains a response that means API request failed. + if (e.response != null) { import com.google.gson.GsonBuilder logger error @@ -106,6 +114,7 @@ class MornyCoeur (using val config: MornyConfig) { | server responses: |${GsonBuilder().setPrettyPrinting().create.toJson(e.response) indent 4} |""".stripMargin + this.daemons.reporter.exception(e, "Failed get updates.") } if (e.getCause != null) { @@ -119,15 +128,17 @@ class MornyCoeur (using val config: MornyConfig) { import scala.collection.mutable val log = mutable.ArrayBuffer(s"Failed get updates: Network Error") var current: Throwable = e_timeout - log += s" due to: ${current.getMessage}" + log += s" due to: ${current.getClass.getSimpleName}: ${current.getMessage}" while (current.getCause != null) { current = current.getCause log += s" caused by: ${current.getClass.getSimpleName}: ${current.getMessage}" } logger error Message(log mkString "\n") case e_other => - logger error exceptionLog(e_other) - this.daemons.reporter exception e_other + logger error + s"""Failed get updates: + |${exceptionLog(e_other) indent 3}""".stripMargin + this.daemons.reporter.exception(e_other, "Failed get updates.") } }) diff --git a/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala b/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala index 307401a..2ede970 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala @@ -19,6 +19,7 @@ import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.model.User import com.pengrad.telegrambot.request.{BaseRequest, SendMessage} import com.pengrad.telegrambot.response.BaseResponse +import com.pengrad.telegrambot.TelegramException import java.time.ZoneId @@ -32,13 +33,20 @@ class MornyReport (using coeur: MornyCoeur) { if !enabled then return; try { coeur.account exec report - } catch case e: EventRuntimeException.ActionFailed => { - logger warn - s"""cannot execute report to telegram: - |${exceptionLog(e) indent 4} - | tg-api response: - |${(e.response toString) indent 4}""" - .stripMargin + } catch case e: EventRuntimeException => { + import EventRuntimeException.* + e match + case e: ActionFailed => + logger warn + s"""cannot execute report to telegram: + |${exceptionLog(e) indent 4} + | tg-api response: + |${(e.response toString) indent 4}""".stripMargin + case e: ClientFailed => + logger error + s"""failed when report to telegram: + |${exceptionLog(e.getCause) indent 4} + |""".stripMargin } } @@ -48,6 +56,10 @@ class MornyReport (using coeur: MornyCoeur) { // language=html "\n\ntg-api error:\n
%s
"
.formatted(GsonBuilder().setPrettyPrinting().create.toJson(api.response))
+ case tgErr: TelegramException if tgErr.response != null =>
+ // language=html
+ "\n\ntg-api error:\n%s
"
+ .formatted(GsonBuilder().setPrettyPrinting().create.toJson(tgErr.response))
case _ => ""
executeReport(SendMessage(
coeur.config.reportToChat,
diff --git a/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/TelegramExtensions.scala b/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/TelegramExtensions.scala
index 5e38eeb..f066792 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/TelegramExtensions.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/TelegramExtensions.scala
@@ -12,13 +12,17 @@ object TelegramExtensions {
object Bot { extension (bot: TelegramBot) {
+ @throws[EventRuntimeException]
def exec [T <: BaseRequest[T, R], R <: BaseResponse] (request: T, onError_message: String = ""): R = {
- val response = bot execute request
- if response isOk then return response
- throw EventRuntimeException.ActionFailed(
- if onError_message isEmpty then response.errorCode toString else onError_message,
- response
- )
+ try {
+ val response = bot execute request
+ if response isOk then return response
+ throw EventRuntimeException.ActionFailed(
+ if onError_message isEmpty then response.errorCode toString else onError_message,
+ response
+ )
+ } catch case e: RuntimeException =>
+ throw EventRuntimeException.ClientFailed(e)
}
}}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/event/EventRuntimeException.scala b/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/event/EventRuntimeException.scala
index b44e7be..dfc3e86 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/event/EventRuntimeException.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/util/tgapi/event/EventRuntimeException.scala
@@ -2,8 +2,26 @@ package cc.sukazyo.cono.morny.util.tgapi.event
import com.pengrad.telegrambot.response.BaseResponse
-class EventRuntimeException (message: String) extends RuntimeException(message)
+/** All possible exception when do Telegram Request.
+ *
+ * Contains following detailed exceptions:
+ * - [[EventRuntimeException.ClientFailed]]
+ * - [[EventRuntimeException.ActionFailed]]
+ */
+abstract class EventRuntimeException (message: String) extends RuntimeException(message)
object EventRuntimeException {
+ /** Telegram API request failed due to the response code is not 200 OK.
+ * @param response Raw API response object.
+ */
class ActionFailed (message: String, val response: BaseResponse) extends EventRuntimeException(message)
+ /** Client exception occurred when sending request.
+ *
+ * It may be some network exception, or parsing API response exception.
+ *
+ * The client exception is stored in [[getCause]].
+ */
+ class ClientFailed (caused: Exception) extends EventRuntimeException("API client failed.") {
+ this.initCause(caused)
+ }
}