
Designing a safe error handling package in Go: safe by default
Error handling in Go is simple. Sometimes too simple. A fmt.Errorf("pq: no rows in result set") bubbling up to an HTTP handler, and suddenly SQL internals are exposed in a 500 response. No exotic vulnerability required — just an err.Error() in the wrong place. This problem is systemic. It doesn't stem from a lack of discipline, but from the absence of a boundary in the type system. Nothing in the error interface distinguishes what is safe to expose from what is not. The concrete problem Here is the classic leak pattern. A handler that serves err.Error() directly in its JSON response, and a repository layer that wraps errors with technical context: // HTTP handler func ( h * Handler ) GetOrder ( c echo . Context ) error { order , err := h . service . FindByID ( ctx , id ) if err != nil { return c . JSON ( http . StatusInternalServerError , map [ string ] string { "error" : err . Error (), // ← LEAK }) } return c . JSON ( http . StatusOK , order ) } // repository layer func ( r * Repo )
Continue reading on Dev.to
Opens in a new tab
