Add catchingExceptions method to replace runCatching (#4797)
- Add `runCatchingExceptions` and `mapCatchingExceptions` to replace `runCatching` and `mapCatching`.
- Make `tryOrNull { ... }` catch only exceptions too.
- Apply the changes to the whole project.
- Add new Rust fakes for tests to handle the code that's now unblocked - previously it just threw an `UnsatisfiedLinkError` which we ignored.
- Add a new `detekt-rules` project with a `RunCatchingRule` to prevent `runCatching` and `mapCatching` usages.
This commit is contained in:
parent
7816529fd7
commit
efdc10e60a
144 changed files with 716 additions and 375 deletions
1
tests/detekt-rules/.gitignore
vendored
Normal file
1
tests/detekt-rules/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
20
tests/detekt-rules/build.gradle.kts
Normal file
20
tests/detekt-rules/build.gradle.kts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
plugins {
|
||||
alias(libs.plugins.kotlin.jvm)
|
||||
}
|
||||
java {
|
||||
sourceCompatibility = Versions.javaVersion
|
||||
targetCompatibility = Versions.javaVersion
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion = Versions.javaLanguageVersion
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.test.detekt.api)
|
||||
testImplementation(libs.test.detekt.test)
|
||||
|
||||
testImplementation(libs.test.truth)
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.detektrules
|
||||
|
||||
import io.gitlab.arturbosch.detekt.api.Config
|
||||
import io.gitlab.arturbosch.detekt.api.RuleSet
|
||||
import io.gitlab.arturbosch.detekt.api.RuleSetProvider
|
||||
|
||||
class ElementRuleSetProvider : RuleSetProvider {
|
||||
override val ruleSetId: String = "ElementXRules"
|
||||
|
||||
override fun instance(config: Config): RuleSet = RuleSet(
|
||||
id = ruleSetId,
|
||||
rules = listOf(
|
||||
RunCatchingRule(config),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.detektrules
|
||||
|
||||
import io.gitlab.arturbosch.detekt.api.CodeSmell
|
||||
import io.gitlab.arturbosch.detekt.api.Config
|
||||
import io.gitlab.arturbosch.detekt.api.Debt
|
||||
import io.gitlab.arturbosch.detekt.api.Entity
|
||||
import io.gitlab.arturbosch.detekt.api.Issue
|
||||
import io.gitlab.arturbosch.detekt.api.Rule
|
||||
import io.gitlab.arturbosch.detekt.api.Severity
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||
|
||||
class RunCatchingRule(config: Config) : Rule(config) {
|
||||
override val issue: Issue = Issue(
|
||||
id = "RunCatchingNotAllowed",
|
||||
severity = Severity.Style,
|
||||
description = "Avoid using `runCatching`, use `runCatchingExceptions` or `tryOrNull` instead. " +
|
||||
"Avoid `mapCatching`, use `mapCatchingExceptions` instead.",
|
||||
debt = Debt.FIVE_MINS,
|
||||
)
|
||||
|
||||
override fun visitCallExpression(expression: KtCallExpression) {
|
||||
super.visitCallExpression(expression)
|
||||
|
||||
val callNameExpression = expression.getCallNameExpression() ?: return
|
||||
val hasRunCatchingCall = callNameExpression.text == "runCatching"
|
||||
val hasMapCatchingCall = callNameExpression.text == "mapCatching"
|
||||
if (hasRunCatchingCall || hasMapCatchingCall) {
|
||||
report(CodeSmell(
|
||||
issue = issue,
|
||||
entity = Entity.from(expression),
|
||||
message = "Use `runCatchingExceptions` or `tryOrNull` instead of `runCatching`. Avoid `mapCatching`, use `mapCatchingExceptions` instead."
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
io.element.android.detektrules.ElementRuleSetProvider
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.detektrules
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.gitlab.arturbosch.detekt.api.Config
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.junit.Test
|
||||
|
||||
class RunCatchingRuleTest {
|
||||
private val subject = RunCatchingRule(Config.empty)
|
||||
|
||||
@Test
|
||||
fun `test RunCatchingRule`() {
|
||||
val findings = subject.compileAndLint(code)
|
||||
assertThat(findings).hasSize(3)
|
||||
}
|
||||
|
||||
private val code = """
|
||||
object Foo {
|
||||
fun bar() {
|
||||
runCatching {}
|
||||
kotlin.runCatching {}
|
||||
Result.success(true).mapCatching { false }
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
|
@ -7,19 +7,8 @@
|
|||
|
||||
package io.element.android.tests.testutils.lambda
|
||||
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
fun lambdaError(
|
||||
message: String = "This lambda should never be called."
|
||||
): Nothing {
|
||||
// Throwing an exception here is not enough, it can be caught.
|
||||
// Instead exit the process to make sure the test fails.
|
||||
// The error will be:
|
||||
// "Could not stop all services."
|
||||
// In this case, put a breakpoint here and run the test in debug mode to identify which lambda is failing.
|
||||
System.err.println(message)
|
||||
Thread.currentThread().stackTrace.forEach {
|
||||
System.err.println(it)
|
||||
}
|
||||
exitProcess(1)
|
||||
throw AssertionError(message)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue