fix request client failed caused unexpected exception

This commit is contained in:
A.C.Sukazyo Eyre 2023-11-22 16:06:15 +08:00
parent f8b2d056cc
commit 43cdf221d9
Signed by: Eyre_S
GPG Key ID: C17CE40291207874
5 changed files with 63 additions and 18 deletions

View File

@ -5,7 +5,7 @@ MORNY_ARCHIVE_NAME = morny-coeur
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s 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 USE_DELTA = false
VERSION_DELTA = VERSION_DELTA =

View File

@ -99,6 +99,14 @@ class MornyCoeur (using val config: MornyConfig) {
import com.pengrad.telegrambot.TelegramException import com.pengrad.telegrambot.TelegramException
account.setUpdatesListener(eventManager, (e: 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) { if (e.response != null) {
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
logger error logger error
@ -106,6 +114,7 @@ class MornyCoeur (using val config: MornyConfig) {
| server responses: | server responses:
|${GsonBuilder().setPrettyPrinting().create.toJson(e.response) indent 4} |${GsonBuilder().setPrettyPrinting().create.toJson(e.response) indent 4}
|""".stripMargin |""".stripMargin
this.daemons.reporter.exception(e, "Failed get updates.")
} }
if (e.getCause != null) { if (e.getCause != null) {
@ -119,15 +128,17 @@ class MornyCoeur (using val config: MornyConfig) {
import scala.collection.mutable import scala.collection.mutable
val log = mutable.ArrayBuffer(s"Failed get updates: Network Error") val log = mutable.ArrayBuffer(s"Failed get updates: Network Error")
var current: Throwable = e_timeout var current: Throwable = e_timeout
log += s" due to: ${current.getMessage}" log += s" due to: ${current.getClass.getSimpleName}: ${current.getMessage}"
while (current.getCause != null) { while (current.getCause != null) {
current = current.getCause current = current.getCause
log += s" caused by: ${current.getClass.getSimpleName}: ${current.getMessage}" log += s" caused by: ${current.getClass.getSimpleName}: ${current.getMessage}"
} }
logger error Message(log mkString "\n") logger error Message(log mkString "\n")
case e_other => case e_other =>
logger error exceptionLog(e_other) logger error
this.daemons.reporter exception e_other s"""Failed get updates:
|${exceptionLog(e_other) indent 3}""".stripMargin
this.daemons.reporter.exception(e_other, "Failed get updates.")
} }
}) })

View File

@ -19,6 +19,7 @@ import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.model.User import com.pengrad.telegrambot.model.User
import com.pengrad.telegrambot.request.{BaseRequest, SendMessage} import com.pengrad.telegrambot.request.{BaseRequest, SendMessage}
import com.pengrad.telegrambot.response.BaseResponse import com.pengrad.telegrambot.response.BaseResponse
import com.pengrad.telegrambot.TelegramException
import java.time.ZoneId import java.time.ZoneId
@ -32,13 +33,20 @@ class MornyReport (using coeur: MornyCoeur) {
if !enabled then return; if !enabled then return;
try { try {
coeur.account exec report coeur.account exec report
} catch case e: EventRuntimeException.ActionFailed => { } catch case e: EventRuntimeException => {
import EventRuntimeException.*
e match
case e: ActionFailed =>
logger warn logger warn
s"""cannot execute report to telegram: s"""cannot execute report to telegram:
|${exceptionLog(e) indent 4} |${exceptionLog(e) indent 4}
| tg-api response: | tg-api response:
|${(e.response toString) indent 4}""" |${(e.response toString) indent 4}""".stripMargin
.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 // language=html
"\n\ntg-api error:\n<pre><code class='language-json'>%s</code></pre>" "\n\ntg-api error:\n<pre><code class='language-json'>%s</code></pre>"
.formatted(GsonBuilder().setPrettyPrinting().create.toJson(api.response)) .formatted(GsonBuilder().setPrettyPrinting().create.toJson(api.response))
case tgErr: TelegramException if tgErr.response != null =>
// language=html
"\n\ntg-api error:\n<pre><code class='language-json'>%s</code></pre>"
.formatted(GsonBuilder().setPrettyPrinting().create.toJson(tgErr.response))
case _ => "" case _ => ""
executeReport(SendMessage( executeReport(SendMessage(
coeur.config.reportToChat, coeur.config.reportToChat,

View File

@ -12,13 +12,17 @@ object TelegramExtensions {
object Bot { extension (bot: TelegramBot) { object Bot { extension (bot: TelegramBot) {
@throws[EventRuntimeException]
def exec [T <: BaseRequest[T, R], R <: BaseResponse] (request: T, onError_message: String = ""): R = { def exec [T <: BaseRequest[T, R], R <: BaseResponse] (request: T, onError_message: String = ""): R = {
try {
val response = bot execute request val response = bot execute request
if response isOk then return response if response isOk then return response
throw EventRuntimeException.ActionFailed( throw EventRuntimeException.ActionFailed(
if onError_message isEmpty then response.errorCode toString else onError_message, if onError_message isEmpty then response.errorCode toString else onError_message,
response response
) )
} catch case e: RuntimeException =>
throw EventRuntimeException.ClientFailed(e)
} }
}} }}

View File

@ -2,8 +2,26 @@ package cc.sukazyo.cono.morny.util.tgapi.event
import com.pengrad.telegrambot.response.BaseResponse 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 { 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) 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)
}
} }