Мы написали библиотеку Kotlin для обработки сетевой логики. Сама библиотека содержит AsyncTask, который использует возможности HttpURLConnection в java.net.*.
private inner class ClickstreamTask(
headers: HashMap<String, String>,
params: Request,
success: (() -> Unit)? = null,
failure: ((statusCode: Int?, json:
HashMap<String, String>?) -> Unit)? = null) : AsyncTask<Void, Unit, Unit>() {
private var headers: HashMap<String, String> = headers
private var paramaters: Request = params
private var success: (() -> Unit)? = success
private var failure: ((statusCode: Int?, json: HashMap<String, String>?) -> Unit)? = failure
override fun doInBackground(vararg params: Void){
val url = try {
URL(getURLString() + path)
} catch (e: Exception) {
failure?.invoke(null, hashMapOf("error" to "Invalid URL."))
return Unit
}
var request = try{
url.openConnection() as HttpURLConnection
} catch (e: Exception){
failure?.invoke(null, hashMapOf("error" to "Unable to establish connection"))
return Unit
}
request.doInput = false
request.doOutput = true
val mapper = jacksonObjectMapper()
request.requestMethod = "POST"
val httpBody = try {
mapper.writeValueAsBytes(paramaters)
} catch (e: Exception) {
failure?.invoke(null, hashMapOf("error" to "Invalid params."))
return Unit
}
for ((key, value) in headers) {
request.setRequestProperty(key, value)
}
try{
request.outputStream.write(httpBody)
}catch (e: Throwable){
request.outputStream.close()
failure?.invoke(null, hashMapOf("error" to "Issue writing to URL"))
return Unit
}
request.outputStream.close()
if (request.responseCode != 200){
failure?.invoke(request.responseCode, hashMapOf("Failed request" to request.responseMessage))
return Unit
}
success?.invoke()
return Unit
}
}
Когда мы используем приложение Android, которое использует библиотеку в режиме полета, приложение вылетает из-за неперехваченного исключения UnknownHostException:
Caused by: java.net.UnknownHostException: Unable to resolve host "ste03lbclkapp00.iteclientsys.local": No address associated with hostname at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:141) at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90) at java.net.InetAddress.getAllByName(InetAddress.java:787) at com.android.okhttp.Dns$1.lookup(Dns.java:39) at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175) at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141) at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83) at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174) at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126) at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95) at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281) at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258) at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218) at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(Unknown Source:0) at com.tdameritrade.amerivest.clickstreamshared.Network.NetworkManager$ClickstreamTask.doInBackground(NetworkManager.kt:87) at com.tdameritrade.amerivest.clickstreamshared.Network.NetworkManager$ClickstreamTask.doInBackground(NetworkManager.kt:43) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266) ... 4 more Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname) at libcore.io.Linux.android_getaddrinfo(Native Method) at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:59) at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:122) ... 24 more
Строка, вызывающая исключение, - request.outputStream.write(httpBody). Однако мы оборачиваем эту строку в try / catch, который обрабатывает Throwable.
Как doOnBackground() строка 87 выдает исключение, когда оно заключено в catch?
Это был Exception, и я поменял его на Throwable, просто чтобы проверить
Затем в своем блоке исключения, который можно выбросить, вы пытаетесь получить доступ к request.outputstream.close, который, как я предполагаю, затем генерирует исключение, которое находится вне улова.




Этот код:
try{
request.outputStream.write(httpBody)
}catch (e: Throwable){
request.outputStream.close()
failure?.invoke(null, hashMapOf("error" to "Issue writing to URL"))
return Unit
}
попытается выполнить операцию в блоке catch, который также может вызвать исключение:
request.outputStream.close()
Это не обнаружено, но также кажется нецелесообразным, учитывая, что вы обрабатываете ошибку некоторый при доступе к выходному потоку.
Трассировка исключения указывает на другие причины, и я предполагаю, что если копать дальше, вы исправите это.
Я удалил ручей рядом с уловом и никаких изменений в поведении
Опубликуйте полную трассировку стека ... и еще кое-что - полезные вещи обычно находятся внизу цепочки вызванных. Окружите весь код doinbackground исключениями try / catch и log-исключениями.
К., когда вернусь с обеда, попробую. Спасибо
Хотя ловить
Throwable- очень плохая идея.