Skip to content

Commit ecda971

Browse files
Emyrkkylecarbs
authored andcommitted
chore: Add linting rule to help catch InTx misuse (#1980)
* chore: Add linting rule to help catch InTx misuse This isn't perfect, as if you nest your misuse in another code block like an if statement, it won't catch it :/. It is better than nothing
1 parent 02ee7e5 commit ecda971

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

scripts/rules.go

+46
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,49 @@ func doNotCallTFailNowInsideGoroutine(m dsl.Matcher) {
6969
Where(m["t"].Type.Implements("testing.TB") && m["fail"].Text.Matches("^(FailNow|Fatal|Fatalf)$")).
7070
Report("Do not call functions that may call t.FailNow in a goroutine, as this can cause data races (see testing.go:834)")
7171
}
72+
73+
// InTx checks to ensure the database used inside the transaction closure is the transaction
74+
// database, and not the original database that creates the tx.
75+
func InTx(m dsl.Matcher) {
76+
// ':=' and '=' are 2 different matches :(
77+
m.Match(`
78+
$x.InTx(func($y) error {
79+
$*_
80+
$*_ = $x.$f($*_)
81+
$*_
82+
})
83+
`, `
84+
$x.InTx(func($y) error {
85+
$*_
86+
$*_ := $x.$f($*_)
87+
$*_
88+
})
89+
`).Where(m["x"].Text != m["y"].Text).
90+
At(m["f"]).
91+
Report("Do not use the database directly within the InTx closure. Use '$y' instead of '$x'.")
92+
93+
//When using a tx closure, ensure that if you pass the db to another
94+
//function inside the closure, it is the tx.
95+
//This will miss more complex cases such as passing the db as apart
96+
//of another struct.
97+
m.Match(`
98+
$x.InTx(func($y database.Store) error {
99+
$*_
100+
$*_ = $f($*_, $x, $*_)
101+
$*_
102+
})
103+
`, `
104+
$x.InTx(func($y database.Store) error {
105+
$*_
106+
$*_ := $f($*_, $x, $*_)
107+
$*_
108+
})
109+
`, `
110+
$x.InTx(func($y database.Store) error {
111+
$*_
112+
$f($*_, $x, $*_)
113+
$*_
114+
})
115+
`).Where(m["x"].Text != m["y"].Text).
116+
At(m["f"]).Report("Pass the tx database into the '$f' function inside the closure. Use '$y' over $x'")
117+
}

0 commit comments

Comments
 (0)