Improve Git error message handling (#1011)

Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Fabian Henneke
2020-08-12 10:50:08 +02:00
committed by GitHub
parent 372c0f3dbd
commit d08397872a
3 changed files with 24 additions and 37 deletions

View File

@@ -6,58 +6,48 @@
package com.zeapo.pwdstore.git
import android.os.RemoteException
import androidx.annotation.StringRes
import com.zeapo.pwdstore.Application
import com.zeapo.pwdstore.R
import java.net.UnknownHostException
/**
* Supertype for all Git-related [Exception]s that can be thrown by [GitCommandExecutor.execute].
*/
sealed class GitException(message: String? = null) : Exception(message) {
sealed class GitException(@StringRes res: Int, vararg fmt: String) : Exception(buildMessage(res, *fmt)) {
override val message = super.message!!
companion object {
private fun buildMessage(@StringRes res: Int, vararg fmt: String) = Application.instance.resources.getString(res, *fmt)
}
/**
* Encapsulates possible errors from a [org.eclipse.jgit.api.PullCommand].
*/
class PullException(val reason: Reason) : GitException() {
enum class Reason {
REBASE_FAILED,
}
sealed class PullException(@StringRes res: Int, vararg fmt: String) : GitException(res, *fmt) {
object PullRebaseFailed : PullException(R.string.git_pull_fail_error)
}
/**
* Encapsulates possible errors from a [org.eclipse.jgit.api.PushCommand].
*/
class PushException(val reason: Reason, vararg val fmt: String) : GitException() {
enum class Reason {
NON_FAST_FORWARD,
REMOTE_REJECTED,
GENERIC,
}
sealed class PushException(@StringRes res: Int, vararg fmt: String) : GitException(res, *fmt) {
object NonFastForward : PushException(R.string.git_push_nff_error)
object RemoteRejected : PushException(R.string.git_push_other_error)
class Generic(message: String) : PushException(R.string.git_push_generic_error, message)
}
}
object ErrorMessages {
private val PULL_REASON_MAP = mapOf(
GitException.PullException.Reason.REBASE_FAILED to R.string.git_pull_fail_error,
)
private val PUSH_REASON_MAP = mapOf(
GitException.PushException.Reason.NON_FAST_FORWARD to R.string.git_push_nff_error,
GitException.PushException.Reason.REMOTE_REJECTED to R.string.git_push_other_error,
GitException.PushException.Reason.GENERIC to R.string.git_push_generic_error,
)
operator fun get(throwable: Throwable?): String {
val resources = Application.instance.resources
if (throwable == null) return resources.getString(R.string.git_unknown_error)
return when (val rootCause = rootCause(throwable)) {
is GitException.PullException -> {
resources.getString(PULL_REASON_MAP.getValue(rootCause.reason))
}
is GitException.PushException -> {
resources.getString(PUSH_REASON_MAP.getValue(rootCause.reason), *rootCause.fmt)
}
is GitException -> rootCause.message
is UnknownHostException -> resources.getString(R.string.git_unknown_host, throwable.message)
else -> throwable.message ?: resources.getString(R.string.git_unknown_error)
}
}

View File

@@ -59,7 +59,7 @@ class GitCommandExecutor(
}
val rr = result.rebaseResult
if (rr.status === RebaseResult.Status.STOPPED) {
operationResult = Result.Err(PullException(PullException.Reason.REBASE_FAILED))
operationResult = Result.Err(PullException.PullRebaseFailed)
}
}
is PushCommand -> {
@@ -70,21 +70,17 @@ class GitCommandExecutor(
// Code imported (modified) from Gerrit PushOp, license Apache v2
for (rru in result.remoteUpdates) {
val error = when (rru.status) {
RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD -> {
PushException(PushException.Reason.NON_FAST_FORWARD)
}
RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD -> PushException.NonFastForward
RemoteRefUpdate.Status.REJECTED_NODELETE,
RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
RemoteRefUpdate.Status.NON_EXISTING,
RemoteRefUpdate.Status.NOT_ATTEMPTED,
-> {
PushException(PushException.Reason.GENERIC, rru.status.name)
}
-> PushException.Generic(rru.status.name)
RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
if ("non-fast-forward" == rru.message) {
PushException(PushException.Reason.REMOTE_REJECTED)
PushException.RemoteRejected
} else {
PushException(PushException.Reason.GENERIC, rru.message)
PushException.Generic(rru.message)
}
}
RemoteRefUpdate.Status.UP_TO_DATE -> {

View File

@@ -374,6 +374,7 @@
<string name="git_push_nff_error">Push was rejected by remote, run pull before pushing again. You can use Synchronize rather than pull/push as it implements both</string>
<string name="git_push_generic_error">Push was rejected by remote, reason: %1$s</string>
<string name="git_push_other_error">Remote rejected non-fast-forward push. Check receive.denyNonFastForwards variable in config file of destination repository.</string>
<string name="git_unknown_host">Unknown host: %1$s</string>
<string name="git_operation_running">Running git operation…</string>
<!-- OpenKeychain not installed -->