Fix previous workaround by handling fake http 404 errors

This commit is contained in:
Mikołaj Pich 2023-05-07 21:27:32 +02:00
parent 8973b01694
commit 14267a9a89
7 changed files with 26 additions and 18 deletions

View file

@ -29,6 +29,10 @@ public final class io/github/wulkanowy/sdk/hebe/exception/InvalidPinException :
public fun <init> ()V
}
public final class io/github/wulkanowy/sdk/hebe/exception/InvalidSymbolException : java/io/IOException {
public fun <init> ()V
}
public final class io/github/wulkanowy/sdk/hebe/exception/InvalidTokenException : java/io/IOException {
public fun <init> (Ljava/lang/String;)V
}

View file

@ -389,6 +389,7 @@ public class io/github/wulkanowy/sdk/scrapper/exception/PasswordResetErrorExcept
}
public class io/github/wulkanowy/sdk/scrapper/exception/ScrapperException : java/io/IOException {
public final fun getCode ()I
}
public final class io/github/wulkanowy/sdk/scrapper/exception/ServiceUnavailableException : io/github/wulkanowy/sdk/scrapper/exception/VulcanException {

View file

@ -1,3 +1,3 @@
package io.github.wulkanowy.sdk.scrapper.exception
open class VulcanException internal constructor(message: String) : ScrapperException(message)
open class VulcanException internal constructor(message: String, httpCode: Int = -1) : ScrapperException(message, httpCode)

View file

@ -16,6 +16,7 @@ import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.slf4j.LoggerFactory
import java.net.CookieManager
import java.net.HttpURLConnection.HTTP_NOT_FOUND
internal class ErrorInterceptor(
private val cookies: CookieManager,
@ -31,16 +32,23 @@ internal class ErrorInterceptor(
if (response.body?.contentType()?.subtype != "json") {
val url = response.request.url.toString()
checkForError(Jsoup.parse(response.peekBody(Long.MAX_VALUE).byteStream(), null, url), url)
checkForError(
doc = Jsoup.parse(response.peekBody(Long.MAX_VALUE).byteStream(), null, url),
redirectUrl = url,
httpCode = response.code,
)
}
return response
}
private fun checkForError(doc: Document, redirectUrl: String) {
private fun checkForError(doc: Document, redirectUrl: String, httpCode: Int) {
doc.select(".errorBlock").let {
if (it.isNotEmpty()) {
throw VulcanException("${it.select(".errorTitle").text()}. ${it.select(".errorMessage").text()}")
when (val title = it.select(".errorTitle").text()) {
"HTTP Error 404" -> throw ScrapperException(title, HTTP_NOT_FOUND)
else -> throw VulcanException("$title. ${it.select(".errorMessage").text()}", httpCode)
}
}
}
@ -55,7 +63,7 @@ internal class ErrorInterceptor(
doc.select("#MainPage_ErrorDiv div").let {
if (it.text().contains("Trwa aktualizacja bazy danych")) throw ServiceUnavailableException(it.last()?.ownText().orEmpty())
if (it.last()?.ownText()?.contains("czasowo wyłączona") == true) throw TemporarilyDisabledException(it.last()?.ownText().orEmpty())
if (it.isNotEmpty()) throw VulcanException(it[0].ownText())
if (it.isNotEmpty()) throw VulcanException(it[0].ownText(), httpCode)
}
doc.select("h2.error").let {
@ -76,26 +84,24 @@ internal class ErrorInterceptor(
}
when (doc.title()) {
"Błąd" -> throw VulcanException(doc.body().text())
"Błąd strony" -> throw VulcanException(doc.select(".errorMessage").text())
"Błąd" -> throw VulcanException(doc.body().text(), httpCode)
"Błąd strony" -> throw VulcanException(doc.select(".errorMessage").text(), httpCode)
"Logowanie" -> throw AccountPermissionException(doc.select("div").last()?.ownText().orEmpty().split(" Jeśli")[0])
"Login Service" -> {
cookies.cookieStore.removeAll() // workaround for very strange (random) errors
throw ScrapperException(doc.select("#MainDiv > div").text())
throw ScrapperException(doc.select("#MainDiv > div").text(), httpCode)
}
"Połączenie zablokowane" -> throw ConnectionBlockedException(doc.body().text())
"Just a moment..." -> if (doc.select(".footer").text().contains("Cloudflare")) {
throw ConnectionBlockedException(doc.select("#challenge-body-text").text())
}
"Przerwa techniczna" -> throw ServiceUnavailableException(doc.title())
"Strona nie została odnaleziona" -> throw ScrapperException(doc.title())
"Strona nie znaleziona" -> throw ScrapperException(doc.selectFirst("div div")?.text().orEmpty())
"Strona nie została odnaleziona" -> throw ScrapperException(doc.title(), httpCode)
"Strona nie znaleziona" -> throw ScrapperException(doc.selectFirst("div div")?.text().orEmpty(), httpCode)
}
doc.select("h2").text().let {
if (it == "Strona nie znaleziona") throw ScrapperException(it)
if (it == "Strona nie znaleziona") throw ScrapperException(it, httpCode)
}
if (isBobCmn(doc, redirectUrl)) {
throw ConnectionBlockedException("Połączenie zablokowane przez system antybotowy. Spróbuj ponownie za chwilę")
}

View file

@ -35,7 +35,6 @@ import org.jsoup.Jsoup
import org.jsoup.parser.Parser
import org.jsoup.select.Elements
import org.slf4j.LoggerFactory
import retrofit2.HttpException
import java.net.HttpURLConnection
import java.nio.charset.StandardCharsets
@ -252,10 +251,10 @@ internal class RegisterRepository(
private suspend fun getStudentCache(): CacheResponse? {
val startPage = runCatching {
student.getStart("App")
student.getStart(url.generate(UrlGenerator.Site.STUDENT) + "App")
}.recoverCatching {
if (it is ScrapperException && it.code == HttpURLConnection.HTTP_NOT_FOUND) {
student.getStart("Start")
student.getStart(url.generate(UrlGenerator.Site.STUDENT) + "Start")
} else throw it
}.getOrThrow()

View file

@ -56,7 +56,6 @@ import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableHeaders
import io.github.wulkanowy.sdk.scrapper.timetable.mapTimetableList
import io.github.wulkanowy.sdk.scrapper.toFormat
import org.jsoup.Jsoup
import retrofit2.HttpException
import java.net.HttpURLConnection.HTTP_NOT_FOUND
import java.time.LocalDate

View file

@ -176,7 +176,6 @@ internal class ServiceManager(
return getRetrofit(getClientBuilder(), urlGenerator.generate(UrlGenerator.Site.HOME), json = true).create()
}
@OptIn(ExperimentalSerializationApi::class)
private fun getRetrofit(client: OkHttpClient.Builder, baseUrl: String, json: Boolean = false) = Retrofit.Builder()
.baseUrl(baseUrl)
.client(client.build())