Модификация 2. Как обработать ошибку JSON внутри ответа, если код равен 200 - PullRequest
0 голосов
/ 18 ноября 2018

Я использую Vk Api, и в течение 1 сценария я получаю объект ответа с кодом 200, но текст сообщения об ошибке - JSON.

Я хочу спросить вас - возможно ли каким-то образом получить объект ошибки из ответа и посмотреть на error_code, который был возвращен из Vk Api.

Я использую Retrofit 2 на Android и GsonConverterFactory.

Я пытаюсь сделать что-то вроде этого:

class NetworkCheckerInterceptor(val networkChecker: NetworkChecker) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val requestBuilder = chain.request().newBuilder()
        if (!networkChecker.isConnected()) {
            throw NoNetworkConnectionException("No network connection.")
        }
        try {
            val response =  chain.proceed(requestBuilder.build())
            val error = Gson().fromJson(response.body()?.string(), Error::class.java)
            return response
        } catch (e: SocketTimeoutException) {
            throw SocketTimeoutException()
        } catch (e: UnknownHostException) {
            throw UnknownHostException()
        }
    }
}

Но я получаю сообщение об ошибке при попытке получить объект «Ошибка».

Пример ошибки Json:

  {
  "error": {
    "error_code": 7,
    "error_msg": "Permission to perform this action is denied",
    "request_params": [
      {
        "key": "oauth",
        "value": "1"
      },
      {
        "key": "method",
        "value": "stats.get"
      },
      {
        "key": "timestamp_to",
        "value": "1542549195"
      },
      {
        "key": "month",
        "value": "month"
      },
      {
        "key": "group_id",
        "value": "56461699"
      },
      {
        "key": "v",
        "value": "5.87"
      },
      {
        "key": "interval",
        "value": "month"
      },
      {
        "key": "stats_groups",
        "value": "visitors"
      },
      {
        "key": "timestamp_from",
        "value": "1514757660"
      }
    ]
  }
}

Единственное, что меня волнует, это "error_code": 7, это проблема разрешения.

Итак, как я могу получить этот объект, даже если мой код ответа 200?

1 Ответ

0 голосов
/ 18 ноября 2018

Вы можете создать базовый класс для сетевого ответа ВКонтакте

abstract class BaseVkResponse<T> {
    var response: T? = null
    var error: VKError? = null // (from vk sdk)
}

, и каждый ответ должен расширять его.Например,

class NewsItem {
    var type: String? = null
    var text: String? = null
    var date: Long? = null
}

class NewsPage {
    var items: List<NewsItem>? = null
    @SerializedName("nextFrom")
    var nextFrom: String? = null
}

class NewsResponse : BaseVkResponse<NewsPage>()

и интерфейс модификации выглядит как

interface VkService {
    @GET("newsfeed.getRecommended")
    fun getNews(@Query("access_token") accessToken: String,
                @Query("v") apiVersion: String,
                @Query("count") count: Int?,
                @Query("start_from") startFrom: String?): Single<NewsResponse>
}

. Затем зарегистрируйте адаптер специального типа для анализа типа VkError

internal class ErrorTypeAdapter : JsonDeserializer<VKError> {

    @Throws(JsonParseException::class)
    override fun deserialize(json: JsonElement,
                             typeOfT: Type,
                             context: JsonDeserializationContext
    ): VKError? {
        return try {
            VKError(JSONObject(json.toString()))
        } catch (e: JSONException) {
            null
        }
    }
}

val gson = GsonBuilder().apply {
    registerTypeAdapter(VKError::class.java, ErrorTypeAdapter())
}

Если поле ответа error имеет значениене нуль, вы должны обращаться с этим, как вы хотите.В других случаях вы можете считать это успешным.

...