Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite ExceptionUtils methods as extension functions. #4947

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -50,14 +50,14 @@
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory;
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
75 changes: 75 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,75 @@
@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>()

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

/**
* Calls [hasCause] with a reified [Throwable] type.
*/
inline fun <reified T : Throwable> Throwable.hasExactCause() = hasExactCause(T::class.java)

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

/**
* Calls [hasCause] with a reified [Throwable] type.
*/
inline fun <reified T : Throwable> Throwable?.hasAssignableCause() = hasAssignableCause(T::class.java)

/**
* 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 @@ -50,13 +50,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 @@ -344,7 +344,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 @@ -36,11 +36,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 @@ -35,8 +35,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
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 @@ -58,6 +58,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>())
assertTrue(Exception().hasAssignableCause<Exception>())
assertTrue(IOException().hasAssignableCause<Exception>())

assertTrue(IOException().hasAssignableCause<IOException>())
assertTrue(Exception(SocketException()).hasAssignableCause<IOException>())
assertTrue(Exception(IllegalStateException()).hasAssignableCause<RuntimeException>())
assertTrue(Exception(Exception(IOException())).hasAssignableCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(IOException()))).hasAssignableCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(SocketException()))).hasAssignableCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(SSLException("IO")))).hasAssignableCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause<RuntimeException>())

assertTrue(IllegalStateException().hasAssignableCause<Throwable>())
assertTrue(IllegalStateException().hasAssignableCause<Exception>())
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasAssignableCause<InterruptedIOException>())
}

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

@Test fun `exact causes`() {
assertTrue(Throwable().hasExactCause<Throwable>())
assertTrue(Exception().hasExactCause<Exception>())

assertTrue(IOException().hasExactCause<IOException>())
assertTrue(Exception(SocketException()).hasExactCause<SocketException>())
assertTrue(Exception(Exception(IOException())).hasExactCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(IOException()))).hasExactCause<IOException>())
assertTrue(Exception(IllegalStateException(Exception(SocketException()))).hasExactCause<SocketException>())
assertTrue(Exception(IllegalStateException(Exception(SSLException("IO")))).hasExactCause<SSLException>())
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasExactCause<InterruptedIOException>())
assertTrue(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasExactCause<IllegalStateException>())
}

@Test fun `no exact causes`() {
assertFalse(Throwable().hasExactCause<Exception>())
assertFalse(Exception().hasExactCause<Throwable>())

assertFalse(SocketException().hasExactCause<IOException>())
assertFalse(IllegalStateException().hasExactCause<RuntimeException>())
assertFalse(Exception(SocketException()).hasExactCause<IOException>())
assertFalse(Exception(IllegalStateException(Exception(IOException()))).hasExactCause<RuntimeException>())
assertFalse(Exception(IllegalStateException(Exception(SocketException()))).hasExactCause<IOException>())
assertFalse(Exception(IllegalStateException(Exception(InterruptedIOException()))).hasExactCause<IOException>())
}
}
69 changes: 0 additions & 69 deletions app/src/test/java/org/schabi/newpipe/util/ExceptionUtilsTest.kt

This file was deleted.