CommunicationError to Object with static methods
This commit is contained in:
parent
ed152fa52a
commit
1ed9360bc7
|
@ -20,7 +20,6 @@ package org.moire.ultrasonic.util;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import org.moire.ultrasonic.service.CommunicationErrorUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sindre Mehus
|
* @author Sindre Mehus
|
||||||
|
@ -54,12 +53,12 @@ public abstract class BackgroundTask<T> implements ProgressListener
|
||||||
|
|
||||||
protected void error(Throwable error)
|
protected void error(Throwable error)
|
||||||
{
|
{
|
||||||
CommunicationErrorUtil.Companion.handleError(error, activity);
|
CommunicationError.handleError(error, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getErrorMessage(Throwable error)
|
protected String getErrorMessage(Throwable error)
|
||||||
{
|
{
|
||||||
return CommunicationErrorUtil.Companion.getErrorMessage(error, activity);
|
return CommunicationError.getErrorMessage(error, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,9 +18,9 @@ import org.koin.core.component.inject
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
import org.moire.ultrasonic.data.ServerSetting
|
import org.moire.ultrasonic.data.ServerSetting
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
import org.moire.ultrasonic.domain.MusicFolder
|
||||||
import org.moire.ultrasonic.service.CommunicationErrorUtil
|
|
||||||
import org.moire.ultrasonic.service.MusicService
|
import org.moire.ultrasonic.service.MusicService
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
|
import org.moire.ultrasonic.util.CommunicationError
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +94,7 @@ open class GenericListModel(application: Application) :
|
||||||
|
|
||||||
private fun handleException(exception: Exception, context: Context) {
|
private fun handleException(exception: Exception, context: Context) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
CommunicationErrorUtil.handleError(exception, context)
|
CommunicationError.handleError(exception, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import java.util.ArrayList
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import java.util.concurrent.CancellationException
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
@ -67,7 +68,6 @@ import org.moire.ultrasonic.domain.RepeatMode
|
||||||
import org.moire.ultrasonic.featureflags.Feature
|
import org.moire.ultrasonic.featureflags.Feature
|
||||||
import org.moire.ultrasonic.featureflags.FeatureStorage
|
import org.moire.ultrasonic.featureflags.FeatureStorage
|
||||||
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
|
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
|
||||||
import org.moire.ultrasonic.service.CommunicationErrorUtil
|
|
||||||
import org.moire.ultrasonic.service.DownloadFile
|
import org.moire.ultrasonic.service.DownloadFile
|
||||||
import org.moire.ultrasonic.service.LocalMediaPlayer
|
import org.moire.ultrasonic.service.LocalMediaPlayer
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
import org.moire.ultrasonic.service.MediaPlayerController
|
||||||
|
@ -77,6 +77,7 @@ import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
||||||
import org.moire.ultrasonic.subsonic.NetworkAndStorageChecker
|
import org.moire.ultrasonic.subsonic.NetworkAndStorageChecker
|
||||||
import org.moire.ultrasonic.subsonic.ShareHandler
|
import org.moire.ultrasonic.subsonic.ShareHandler
|
||||||
import org.moire.ultrasonic.util.CancellationToken
|
import org.moire.ultrasonic.util.CancellationToken
|
||||||
|
import org.moire.ultrasonic.util.CommunicationError
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
|
@ -84,7 +85,6 @@ import org.moire.ultrasonic.view.AutoRepeatButton
|
||||||
import org.moire.ultrasonic.view.SongListAdapter
|
import org.moire.ultrasonic.view.SongListAdapter
|
||||||
import org.moire.ultrasonic.view.VisualizerView
|
import org.moire.ultrasonic.view.VisualizerView
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.CancellationException
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the Music Player screen of Ultrasonic with playback controls and the playlist
|
* Contains the Music Player screen of Ultrasonic with playback controls and the playlist
|
||||||
|
@ -236,7 +236,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
|
|
||||||
previousButton.setOnClickListener {
|
previousButton.setOnClickListener {
|
||||||
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
mediaPlayerController.previous()
|
mediaPlayerController.previous()
|
||||||
onCurrentChanged()
|
onCurrentChanged()
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
|
@ -250,7 +250,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
|
|
||||||
nextButton.setOnClickListener {
|
nextButton.setOnClickListener {
|
||||||
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
mediaPlayerController.next()
|
mediaPlayerController.next()
|
||||||
onCurrentChanged()
|
onCurrentChanged()
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
|
@ -262,14 +262,14 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
changeProgress(incrementTime)
|
changeProgress(incrementTime)
|
||||||
}
|
}
|
||||||
pauseButton.setOnClickListener {
|
pauseButton.setOnClickListener {
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
mediaPlayerController.pause()
|
mediaPlayerController.pause()
|
||||||
onCurrentChanged()
|
onCurrentChanged()
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stopButton.setOnClickListener {
|
stopButton.setOnClickListener {
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
mediaPlayerController.reset()
|
mediaPlayerController.reset()
|
||||||
onCurrentChanged()
|
onCurrentChanged()
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
|
@ -277,7 +277,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
}
|
}
|
||||||
startButton.setOnClickListener {
|
startButton.setOnClickListener {
|
||||||
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
start()
|
start()
|
||||||
onCurrentChanged()
|
onCurrentChanged()
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
|
@ -309,7 +309,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
|
|
||||||
progressBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
|
progressBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
|
||||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
mediaPlayerController.seekTo(progressBar.progress)
|
mediaPlayerController.seekTo(progressBar.progress)
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
|
|
||||||
playlistView.setOnItemClickListener { _, _, position, _ ->
|
playlistView.setOnItemClickListener { _, _, position, _ ->
|
||||||
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
mediaPlayerController.play(position)
|
mediaPlayerController.play(position)
|
||||||
onCurrentChanged()
|
onCurrentChanged()
|
||||||
onSliderProgressChanged()
|
onSliderProgressChanged()
|
||||||
|
@ -388,7 +388,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query the Jukebox state off-thread
|
// Query the Jukebox state off-thread
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
try {
|
try {
|
||||||
jukeboxAvailable = mediaPlayerController.isJukeboxAvailable
|
jukeboxAvailable = mediaPlayerController.isJukeboxAvailable
|
||||||
} catch (all: Exception) {
|
} catch (all: Exception) {
|
||||||
|
@ -795,7 +795,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"%s %s",
|
"%s %s",
|
||||||
resources.getString(R.string.download_playlist_error),
|
resources.getString(R.string.download_playlist_error),
|
||||||
CommunicationErrorUtil.getErrorMessage(it, context)
|
CommunicationError.getErrorMessage(it, context)
|
||||||
)
|
)
|
||||||
Util.toast(context, msg)
|
Util.toast(context, msg)
|
||||||
}
|
}
|
||||||
|
@ -934,7 +934,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
onProgressChangedTask = scope.launch(CommunicationErrorUtil.handler(context)) {
|
onProgressChangedTask = scope.launch(CommunicationError.getHandler(context)) {
|
||||||
|
|
||||||
val isJukeboxEnabled: Boolean = mediaPlayerController.isJukeboxEnabled
|
val isJukeboxEnabled: Boolean = mediaPlayerController.isJukeboxEnabled
|
||||||
val millisPlayed = max(0, mediaPlayerController.playerPosition)
|
val millisPlayed = max(0, mediaPlayerController.playerPosition)
|
||||||
|
@ -1016,7 +1016,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun changeProgress(ms: Int) {
|
private fun changeProgress(ms: Int) {
|
||||||
scope.launch(CommunicationErrorUtil.handler(context)) {
|
scope.launch(CommunicationError.getHandler(context)) {
|
||||||
val msPlayed: Int = max(0, mediaPlayerController.playerPosition)
|
val msPlayed: Int = max(0, mediaPlayerController.playerPosition)
|
||||||
val duration = mediaPlayerController.playerDuration
|
val duration = mediaPlayerController.playerDuration
|
||||||
val seekTo = (msPlayed + ms).coerceAtMost(duration)
|
val seekTo = (msPlayed + ms).coerceAtMost(duration)
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
import org.moire.ultrasonic.domain.MusicDirectory
|
||||||
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.getTitle
|
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.getTitle
|
||||||
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
|
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
|
||||||
import org.moire.ultrasonic.service.CommunicationErrorUtil
|
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
import org.moire.ultrasonic.service.MediaPlayerController
|
||||||
import org.moire.ultrasonic.subsonic.DownloadHandler
|
import org.moire.ultrasonic.subsonic.DownloadHandler
|
||||||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
||||||
|
@ -47,6 +46,7 @@ import org.moire.ultrasonic.subsonic.ShareHandler
|
||||||
import org.moire.ultrasonic.subsonic.VideoPlayer
|
import org.moire.ultrasonic.subsonic.VideoPlayer
|
||||||
import org.moire.ultrasonic.util.AlbumHeader
|
import org.moire.ultrasonic.util.AlbumHeader
|
||||||
import org.moire.ultrasonic.util.CancellationToken
|
import org.moire.ultrasonic.util.CancellationToken
|
||||||
|
import org.moire.ultrasonic.util.CommunicationError
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
|
import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
|
@ -211,7 +211,7 @@ class TrackCollectionFragment : Fragment() {
|
||||||
|
|
||||||
val handler = CoroutineExceptionHandler { _, exception ->
|
val handler = CoroutineExceptionHandler { _, exception ->
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
CommunicationErrorUtil.handleError(exception, context)
|
CommunicationError.handleError(exception, context)
|
||||||
}
|
}
|
||||||
refreshAlbumListView!!.isRefreshing = false
|
refreshAlbumListView!!.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Subsonic.
|
|
||||||
|
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2020 (C) Jozsef Varga
|
|
||||||
*/
|
|
||||||
package org.moire.ultrasonic.service
|
|
||||||
|
|
||||||
import android.app.AlertDialog
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import com.fasterxml.jackson.core.JsonParseException
|
|
||||||
import java.io.FileNotFoundException
|
|
||||||
import java.io.IOException
|
|
||||||
import java.security.cert.CertPathValidatorException
|
|
||||||
import java.security.cert.CertificateException
|
|
||||||
import javax.net.ssl.SSLException
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
|
||||||
import org.moire.ultrasonic.R
|
|
||||||
import org.moire.ultrasonic.api.subsonic.ApiNotSupportedException
|
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicRESTException
|
|
||||||
import org.moire.ultrasonic.subsonic.getLocalizedErrorMessage
|
|
||||||
import org.moire.ultrasonic.util.Util
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains helper functions to handle the exceptions
|
|
||||||
* thrown during the communication with a Subsonic server
|
|
||||||
*/
|
|
||||||
@Suppress("ReturnCount", "UtilityClassWithPublicConstructor")
|
|
||||||
class CommunicationErrorUtil {
|
|
||||||
companion object {
|
|
||||||
fun handler(context: Context?, handler: ((CoroutineContext, Throwable) -> Unit)? = null):
|
|
||||||
CoroutineExceptionHandler {
|
|
||||||
return CoroutineExceptionHandler { coroutineContext, exception ->
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
handleError(exception, context)
|
|
||||||
handler?.invoke(coroutineContext, exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun handleError(error: Throwable?, context: Context?) {
|
|
||||||
Timber.w(error)
|
|
||||||
|
|
||||||
if (context == null) return
|
|
||||||
|
|
||||||
AlertDialog.Builder(context)
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.setTitle(R.string.error_label)
|
|
||||||
.setMessage(getErrorMessage(error!!, context))
|
|
||||||
.setCancelable(true)
|
|
||||||
.setPositiveButton(R.string.common_ok) { _, _ -> }
|
|
||||||
.create().show()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getErrorMessage(error: Throwable, context: Context?): String {
|
|
||||||
if (context == null) return "Couldn't get Error message, Context is null"
|
|
||||||
if (error is IOException && !Util.isNetworkConnected()) {
|
|
||||||
return context.resources.getString(R.string.background_task_no_network)
|
|
||||||
} else if (error is FileNotFoundException) {
|
|
||||||
return context.resources.getString(R.string.background_task_not_found)
|
|
||||||
} else if (error is JsonParseException) {
|
|
||||||
return context.resources.getString(R.string.background_task_parse_error)
|
|
||||||
} else if (error is SSLException) {
|
|
||||||
return if (
|
|
||||||
error.cause is CertificateException &&
|
|
||||||
error.cause?.cause is CertPathValidatorException
|
|
||||||
) {
|
|
||||||
context.resources
|
|
||||||
.getString(
|
|
||||||
R.string.background_task_ssl_cert_error, error.cause?.cause?.message
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
context.resources.getString(R.string.background_task_ssl_error)
|
|
||||||
}
|
|
||||||
} else if (error is ApiNotSupportedException) {
|
|
||||||
return context.resources.getString(
|
|
||||||
R.string.background_task_unsupported_api, error.serverApiVersion
|
|
||||||
)
|
|
||||||
} else if (error is IOException) {
|
|
||||||
return context.resources.getString(R.string.background_task_network_error)
|
|
||||||
} else if (error is SubsonicRESTException) {
|
|
||||||
return error.getLocalizedErrorMessage(context)
|
|
||||||
}
|
|
||||||
val message = error.message
|
|
||||||
return message ?: error.javaClass.simpleName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* CommunicationErrorUtil.kt
|
||||||
|
* Copyright (C) 2009-2021 Ultrasonic developers
|
||||||
|
*
|
||||||
|
* Distributed under terms of the GNU GPLv3 license.
|
||||||
|
*/
|
||||||
|
package org.moire.ultrasonic.util
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.IOException
|
||||||
|
import java.security.cert.CertPathValidatorException
|
||||||
|
import java.security.cert.CertificateException
|
||||||
|
import javax.net.ssl.SSLException
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
import org.moire.ultrasonic.R
|
||||||
|
import org.moire.ultrasonic.api.subsonic.ApiNotSupportedException
|
||||||
|
import org.moire.ultrasonic.api.subsonic.SubsonicRESTException
|
||||||
|
import org.moire.ultrasonic.subsonic.getLocalizedErrorMessage
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains helper functions to handle the exceptions
|
||||||
|
* thrown during the communication with a Subsonic server
|
||||||
|
*/
|
||||||
|
object CommunicationError {
|
||||||
|
fun getHandler(context: Context?, handler: ((CoroutineContext, Throwable) -> Unit)? = null):
|
||||||
|
CoroutineExceptionHandler {
|
||||||
|
return CoroutineExceptionHandler { coroutineContext, exception ->
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
handleError(exception, context)
|
||||||
|
handler?.invoke(coroutineContext, exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun handleError(error: Throwable?, context: Context?) {
|
||||||
|
Timber.w(error)
|
||||||
|
|
||||||
|
if (context == null) return
|
||||||
|
|
||||||
|
AlertDialog.Builder(context)
|
||||||
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
|
.setTitle(R.string.error_label)
|
||||||
|
.setMessage(getErrorMessage(error!!, context))
|
||||||
|
.setCancelable(true)
|
||||||
|
.setPositiveButton(R.string.common_ok) { _, _ -> }
|
||||||
|
.create().show()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Suppress("ReturnCount")
|
||||||
|
fun getErrorMessage(error: Throwable, context: Context?): String {
|
||||||
|
if (context == null) return "Couldn't get Error message, Context is null"
|
||||||
|
if (error is IOException && !Util.isNetworkConnected()) {
|
||||||
|
return context.resources.getString(R.string.background_task_no_network)
|
||||||
|
} else if (error is FileNotFoundException) {
|
||||||
|
return context.resources.getString(R.string.background_task_not_found)
|
||||||
|
} else if (error is JsonParseException) {
|
||||||
|
return context.resources.getString(R.string.background_task_parse_error)
|
||||||
|
} else if (error is SSLException) {
|
||||||
|
return if (
|
||||||
|
error.cause is CertificateException &&
|
||||||
|
error.cause?.cause is CertPathValidatorException
|
||||||
|
) {
|
||||||
|
context.resources
|
||||||
|
.getString(
|
||||||
|
R.string.background_task_ssl_cert_error, error.cause?.cause?.message
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
context.resources.getString(R.string.background_task_ssl_error)
|
||||||
|
}
|
||||||
|
} else if (error is ApiNotSupportedException) {
|
||||||
|
return context.resources.getString(
|
||||||
|
R.string.background_task_unsupported_api, error.serverApiVersion
|
||||||
|
)
|
||||||
|
} else if (error is IOException) {
|
||||||
|
return context.resources.getString(R.string.background_task_network_error)
|
||||||
|
} else if (error is SubsonicRESTException) {
|
||||||
|
return error.getLocalizedErrorMessage(context)
|
||||||
|
}
|
||||||
|
val message = error.message
|
||||||
|
return message ?: error.javaClass.simpleName
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue