44

I'm looking for a condition check in Go which can terminate the program execution like assert in C++.

Community
  • 1
  • 1
Yixing Liu
  • 2,179
  • 1
  • 20
  • 36
  • 9
    There's not one. Try `if condition { panic(message) }`. – Adrian Nov 29 '17 at 17:27
  • 9
    See also https://golang.org/doc/faq#assertions – Adrian Nov 29 '17 at 17:29
  • 1
    If 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 Answers2

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
  • 1
    Don't use panics, but properly handle the error! https://stackoverflow.com/questions/25356602/golang-panic-crash-prevention – RickyA Nov 30 '17 at 20:39
  • 41
    sry @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