Skip to content

Commit

Permalink
Rewrite ExceptionUtils methods as extension functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Dec 15, 2020
1 parent d46c7eb commit ff7ab1a
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 166 deletions.
2 changes: 1 addition & 1 deletion app/src/main/java/org/schabi/newpipe/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
import org.acra.config.CoreConfigurationBuilder;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.settings.SettingsActivity;
import org.schabi.newpipe.util.ExceptionUtils;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExceptionUtils;
import org.schabi.newpipe.util.InfoCache;

import java.util.Collections;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@
import org.schabi.newpipe.extractor.search.SearchInfo;
import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExceptionUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ServiceHelper;
Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/org/schabi/newpipe/ktx/Throwable.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
@file:JvmName("ExceptionUtils")

package org.schabi.newpipe.ktx

import java.io.IOException
import java.io.InterruptedIOException

/**
* @return if throwable is related to Interrupted exceptions, or one of its causes is.
*/
val Throwable.isInterruptedCaused: Boolean
get() = hasExactCause(InterruptedIOException::class.java, InterruptedException::class.java)

/**
* @return if throwable is related to network issues, or one of its causes is.
*/
val Throwable.isNetworkRelated: Boolean
get() = hasAssignableCause(IOException::class.java)

/**
* Calls [hasCause] with the `checkSubtypes` parameter set to false.
*/
fun Throwable.hasExactCause(vararg causesToCheck: Class<*>) = hasCause(false, *causesToCheck)

/**
* Calls [hasCause] with the `checkSubtypes` parameter set to true.
*/
fun Throwable?.hasAssignableCause(vararg causesToCheck: Class<*>) = hasCause(true, *causesToCheck)

/**
* Check if the throwable has some cause from the causes to check, or is itself in it.
*
* If `checkIfAssignable` is true, not only the exact type will be considered equals, but also its subtypes.
*
* @param checkSubtypes if subtypes are also checked.
* @param causesToCheck an array of causes to check.
*
* @see Class.isAssignableFrom
*/
tailrec fun Throwable?.hasCause(checkSubtypes: Boolean, vararg causesToCheck: Class<*>): Boolean {
if (this == null) {
return false
}

// Check if throwable is a subtype of any of the causes to check
causesToCheck.forEach { causeClass ->
if (checkSubtypes) {
if (causeClass.isAssignableFrom(this.javaClass)) {
return true
}
} else {
if (causeClass == this.javaClass) {
return true
}
}
}

val currentCause: Throwable? = cause
// Check if cause is not pointing to the same instance, to avoid infinite loops.
if (this !== currentCause) {
return currentCause.hasCause(checkSubtypes, *causesToCheck)
}

return false
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.extractor.ListInfo
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.ktx.isNetworkRelated
import org.schabi.newpipe.local.feed.FeedDatabaseManager
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ProgressEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.SuccessResultEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.postEvent
import org.schabi.newpipe.local.subscription.SubscriptionManager
import org.schabi.newpipe.util.ExceptionUtils
import org.schabi.newpipe.util.ExtractorHelper
import java.io.IOException
import java.time.OffsetDateTime
Expand Down Expand Up @@ -342,7 +342,7 @@ class FeedLoadService : Service() {

error is IOException -> throw error
cause is IOException -> throw cause
ExceptionUtils.isNetworkRelated(error) -> throw IOException(error)
error.isNetworkRelated -> throw IOException(error)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
import org.reactivestreams.Publisher;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.local.subscription.SubscriptionManager;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExceptionUtils;

import java.io.FileNotFoundException;
import java.util.Collections;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExceptionUtils;
import org.schabi.newpipe.util.ExtractorHelper;

import java.io.File;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ class ContentSettingsManager(
private val newpipeDb: File,
private val newpipeSettings: File
) {

constructor(homeDir: String) : this(
File("$homeDir/databases/newpipe.db"),
File("$homeDir/databases/newpipe.settings")
constructor(homeDir: File) : this(
File(homeDir, "/databases/newpipe.db"),
File(homeDir, "/databases/newpipe.settings")
)

/**
Expand Down
86 changes: 0 additions & 86 deletions app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.ErrorInfo;
import org.schabi.newpipe.report.UserAction;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.schabi.newpipe.ktx

import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import java.io.IOException
import java.io.InterruptedIOException
import java.net.SocketException
import javax.net.ssl.SSLException

class ThrowableExtensionsTest {
@Test fun `assignable causes`() {
assertTrue(Throwable().hasAssignableCause(Throwable::class.java))
assertTrue(Exception().hasAssignableCause(Exception::class.java))
assertTrue(IOException().hasAssignableCause(Exception::class.java))

assertTrue(IOException().hasAssignableCause(IOException::class.java))
assertTrue(Exception(SocketException()).hasAssignableCause(IOException::class.java))
assertTrue(Exception(IllegalStateException()).hasAssignableCause(RuntimeException::class.java))
assertTrue(Exception(Exception(IOException())).hasAssignableCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(IOException()))).hasAssignableCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(SocketException()))).hasAssignableCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(SSLException("IO")))).hasAssignableCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause(RuntimeException::class.java))

assertTrue(IllegalStateException().hasAssignableCause(Throwable::class.java))
assertTrue(IllegalStateException().hasAssignableCause(Exception::class.java))
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause(InterruptedIOException::class.java))
}

@Test fun `no assignable causes`() {
assertFalse(Throwable().hasAssignableCause(Exception::class.java))
assertFalse(Exception().hasAssignableCause(IOException::class.java))
assertFalse(Exception(IllegalStateException()).hasAssignableCause(IOException::class.java))
assertFalse(Exception(NullPointerException()).hasAssignableCause(IOException::class.java))
assertFalse(Exception(IllegalStateException(Exception(Exception()))).hasAssignableCause(IOException::class.java))
assertFalse(Exception(IllegalStateException(Exception(SocketException()))).hasAssignableCause(InterruptedIOException::class.java))
assertFalse(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause(InterruptedException::class.java))
}

@Test fun `exact causes`() {
assertTrue(Throwable().hasExactCause(Throwable::class.java))
assertTrue(Exception().hasExactCause(Exception::class.java))

assertTrue(IOException().hasExactCause(IOException::class.java))
assertTrue(Exception(SocketException()).hasExactCause(SocketException::class.java))
assertTrue(Exception(Exception(IOException())).hasExactCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(IOException()))).hasExactCause(IOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(SocketException()))).hasExactCause(SocketException::class.java))
assertTrue(Exception(IllegalStateException(Exception(SSLException("IO")))).hasExactCause(SSLException::class.java))
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasExactCause(InterruptedIOException::class.java))
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasExactCause(IllegalStateException::class.java))
}

@Test fun `no exact causes`() {
assertFalse(Throwable().hasExactCause(Exception::class.java))
assertFalse(Exception().hasExactCause(Throwable::class.java))

assertFalse(SocketException().hasExactCause(IOException::class.java))
assertFalse(IllegalStateException().hasExactCause(RuntimeException::class.java))
assertFalse(Exception(SocketException()).hasExactCause(IOException::class.java))
assertFalse(Exception(IllegalStateException(Exception(IOException()))).hasExactCause(RuntimeException::class.java))
assertFalse(Exception(IllegalStateException(Exception(SocketException()))).hasExactCause(IOException::class.java))
assertFalse(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasExactCause(IOException::class.java))
}
}
Loading

0 comments on commit ff7ab1a

Please sign in to comment.