I'm looking for a condition check in Go which can terminate the program execution like assert in C++.
Asked
Active
Viewed 3.1k times
44
-
9There's not one. Try `if condition { panic(message) }`. – Adrian Nov 29 '17 at 17:27
-
9See also https://golang.org/doc/faq#assertions – Adrian Nov 29 '17 at 17:29
-
1If you need it did testing there’s excellent `testing `package Also have a look at https://godoc.org/github.com/stretchr/testify/assert – Eugene Lisitsky Nov 29 '17 at 18:06
-
I understand that it is a design choice to not support assert() in Go. I asked this question just because I wanted to use it in a course project for debugging purpose, not in production. – Yixing Liu Jul 29 '18 at 23:00
-
@EugeneLisitsky assert of testing package requires a test T parameter to be used, that function in the application doesn't have or provide, as they aren't test themselves, but the main code. – Marc Le Bihan Jun 07 '23 at 08:02
2 Answers
46
As mentioned by commenters, Go does not have assertions.
A comparable alternative in Go is the built-in function panic(...)
, gated by a condition:
if condition {
panic(err)
}
This article titled "Defer, Panic, and Recover" may also be informative.

Peter Mortensen
- 30,738
- 21
- 105
- 131

maerics
- 151,642
- 46
- 269
- 291
-
1Don't use panics, but properly handle the error! https://stackoverflow.com/questions/25356602/golang-panic-crash-prevention – RickyA Nov 30 '17 at 20:39
-
41sry @RickyA, but this ignores the stark difference between regular runtime errors and programming/logic bugs: `panic()` in Go (as `assert` in C et al.) is used to signal when a bug has been encountered; you check for invariants that must never be violated (because the code should properly handle error conditions...), but if the invariant is broken, a Bug has occurred. Examples are like "index must be within bounds" when accessing a slice, etc. – gimpf Mar 25 '19 at 14:29
-
I guess the next question is, does an invariant having be violated warrant the program having to halt execution? E.g. imagine the condition being triggered only by some work items in a queue, even if an "invariant" has been violated, I still want to process the next item? – MrR Sep 15 '20 at 19:02
-
@MrR That very much depends on the error. A bad message coming from the message queue in most cases will be skipped with a mere log entry and sent to the DLQ. Repeatedly failing to connect to the main database in most cases will warrant a `panic` (or its unrecoverable cousin - `log.Fatal()`). – Ivaylo Novakov Sep 07 '21 at 13:38
-
So it's eventually possible to create a function implementing that __missing core feature (again)__ in Go. `func assert(condition bool) {if
== false { log.Errorf(...); panic() }}`. But it will be more useful if Golang team accepts to implement it in Go 1.58, in year 2038, or later. – Marc Le Bihan Jun 07 '23 at 07:56
4
I actually use a little helper:
func failIf(err error, msg string) {
if err != nil {
log.Fatalf("error " + msg + ": %v", err)
}
}
And then in use:
db, err := sql.Open("mysql", "my_user@/my_database")
defer db.Close()
failIf(err, "connecting to my_database")
On failure it generates:
error connecting to my_database: <error from MySQL/database>

Peter Mortensen
- 30,738
- 21
- 105
- 131

Dan Jenson
- 961
- 7
- 20