mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-30 22:05:19 +00:00
Improve Git error message handling (#1011)
Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
@@ -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 -> {
|
||||
|
@@ -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 -->
|
||||
|
Reference in New Issue
Block a user