Search code examples
error-handlinggogo-gorm

How can I detect a connection failure in gorm?


I'm writing a small, simple web app in go using the gorm ORM.

Since the database can fail independently of the web application, I'd like to be able to identify errors that correspond to this case so that I can reconnect to my database without restarting the web application.

Motivating example:

Consider the following code:

var mrs MyRowStruct
db := myDB.Model(MyRowStruct{}).Where("column_name = ?", value).First(&mrs)
return &mrs, db.Error
  1. In the event that db.Error != nil, how can I programmatically determine if the error stems from a database connection problem?

  2. From my reading, I understand that gorm.DB does not represent a connection, so do I even have to worry about reconnecting or re-issuing a call to gorm.Open if a database connection fails?

  3. Are there any common patterns for handling database failures in Go?


Solution

  • Gorm appears to swallow database driver errors and emit only it's own classification of error types (see gorm/errors.go). Connection errors do not currently appear to be reported.

    Consider submitting an issue or pull request to expose the database driver error directly.

    [Original]

    Try inspecting the runtime type of db.Error per the advice in the gorm readme "Error Handling" section.

    Assuming it's an error type returned by your database driver you can likely get a specific code that indicates connection errors. For example, if you're using PostgreSQL via the pq library then you might try something like this:

    import "github.com/lib/pq"
    
    // ...
    
    if db.Error != nil {
      pqerr, ok := err.(*pq.Error)
      if ok && pqerr.Code[0:2] == "08" {
        // PostgreSQL "Connection Exceptions" are class "08"
        // http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html#ERRCODES-TABLE
        // Do something for connection errors...
      } else {
        // Do something else with non-pg error or non-connection error...
      }
    }