A simple, lightweight Go package for centralized HTTP error handling, using helper functions to generate standard HTTP error responses directly.
httperror provides a simple way to handle errors in your Go web application without complex middleware configurations. It offers a set of helper functions that directly write standardized JSON (or HTML) error responses to the http.ResponseWriter. It also supports a global error handler configuration for custom error rendering.
go get github.com/DevNewbie1826/httperror- Direct Usage: No middleware required. Call
httperror.NotFound(w, r)directly in your handlers. - Standardized Responses: Default error handler responds with JSON (or HTML for browsers) automatically.
- Customizable: You can replace the default error handler globally using
httperror.SetErrorHandler. - Comprehensive Helpers: Covers almost all standard HTTP error status codes (e.g.,
httperror.BadRequest,httperror.Forbidden, etc.).
Simply import the package and use the helper functions in your HTTP handlers.
package main
import (
"fmt"
"log"
"net/http"
"github.com/DevNewbie1826/httperror"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, World!")
})
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
// Some logic to find a user...
userFound := false
if !userFound {
// Directly respond with a 404 Not Found error.
// This writes the status code and the JSON body to the ResponseWriter.
httperror.NotFound(w, r, "User with the specified ID was not found.")
return
}
fmt.Fprintln(w, "User data would be here.")
})
http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
// Respond with a 403 Forbidden error using the default message.
httperror.Forbidden(w, r)
})
log.Println("Server starting on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}When you run this server and access http://localhost:8080/users, you will get a JSON response like this:
{
"status": 404,
"message": "User with the specified ID was not found."
}You can provide your own custom error handling logic globally using SetErrorHandler. This is useful if you want to render custom HTML error pages or change the JSON structure.
package main
import (
"fmt"
"log"
"net/http"
"github.com/DevNewbie1826/httperror"
)
func main() {
// Set a custom global error handler.
httperror.SetErrorHandler(func(w http.ResponseWriter, r *http.Request, err error) {
// You can type-assert to access the status code if needed
status := http.StatusInternalServerError
message := "Internal Server Error"
if httpErr, ok := err.(*httperror.HttpError); ok {
status = httpErr.Status
message = httpErr.Message
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
fmt.Fprintf(w, `{"error": true, "code": %d, "msg": "%s"}`, status, message)
})
http.HandleFunc("/oops", func(w http.ResponseWriter, r *http.Request) {
httperror.BadRequest(w, r, "Something went wrong!")
})
log.Println("Server starting on :8080")
http.ListenAndServe(":8080", nil)
}httperrorλ 볡μ‘ν λ―Έλ€μ¨μ΄ μ€μ μμ΄ Go μΉ μ ν리μΌμ΄μ
μ μ€λ₯λ₯Ό μ²λ¦¬ν μ μλ κ°λ¨νκ³ κ°λ²Όμ΄ ν¨ν€μ§μ
λλ€. http.ResponseWriterμ νμ€νλ JSON(λλ λΈλΌμ°μ μ κ²½μ° HTML) μ€λ₯ μλ΅μ μ§μ μμ±νλ ν¬νΌ ν¨μλ€μ μ 곡ν©λλ€. λν, μ μ μ€λ₯ νΈλ€λ¬ μ€μ μ ν΅ν΄ 컀μ€ν
λ λλ§ λ‘μ§μ μ μ©ν μ μμ΅λλ€.
go get github.com/DevNewbie1826/httperror- μ§κ΄μ μΈ μ¬μ©: λ―Έλ€μ¨μ΄κ° νμ μμ΅λλ€. νΈλ€λ¬μμ
httperror.NotFound(w, r)μ κ°μ΄ μ§μ νΈμΆνμΈμ. - νμ€νλ μλ΅: κΈ°λ³Έ μ€λ₯ νΈλ€λ¬κ° μλμΌλ‘ JSON(λλ λΈλΌμ°μ μμ² μ HTML)μΌλ‘ μλ΅ν©λλ€.
- 컀μ€ν°λ§μ΄μ§:
httperror.SetErrorHandlerλ₯Ό μ¬μ©νμ¬ κΈ°λ³Έ μ€λ₯ νΈλ€λ¬λ₯Ό μ μμ μΌλ‘ κ΅μ²΄ν μ μμ΅λλ€. - ν¬κ΄μ μΈ ν¬νΌ: κ±°μ λͺ¨λ νμ€ HTTP μ€λ₯ μν μ½λλ₯Ό μ§μν©λλ€ (μ:
httperror.BadRequest,httperror.Forbiddenλ±).
ν¨ν€μ§λ₯Ό import νκ³ HTTP νΈλ€λ¬ λ΄μμ ν¬νΌ ν¨μλ₯Ό μ§μ μ¬μ©νμλ©΄ λ©λλ€.
package main
import (
"fmt"
"log"
"net/http"
"github.com/DevNewbie1826/httperror"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, World!")
})
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
// μ¬μ©μλ₯Ό μ°Ύλ λ‘μ§μ΄ μλ€κ³ κ°μ ...
userFound := false
if !userFound {
// 404 Not Found μ€λ₯λ‘ μ¦μ μλ΅ν©λλ€.
// μ΄ ν¨μκ° μν μ½λμ JSON λ³Έλ¬Έμ ResponseWriterμ μμ±ν©λλ€.
httperror.NotFound(w, r, "μ§μ λ IDμ μ¬μ©μλ₯Ό μ°Ύμ μ μμ΅λλ€.")
return
}
fmt.Fprintln(w, "μ¬μ©μ λ°μ΄ν°κ° μ¬κΈ°μ μΆλ ₯λ©λλ€.")
})
http.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
// κΈ°λ³Έ λ©μμ§λ₯Ό μ¬μ©νμ¬ 403 Forbidden μ€λ₯λ₯Ό μλ΅ν©λλ€.
httperror.Forbidden(w, r)
})
log.Println("Server starting on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}μ΄ μλ²λ₯Ό μ€ννκ³ http://localhost:8080/users μ£Όμλ‘ μ μνλ©΄, λ€μκ³Ό κ°μ JSON μλ΅μ λ°κ² λ©λλ€.
{
"status": 404,
"message": "μ§μ λ IDμ μ¬μ©μλ₯Ό μ°Ύμ μ μμ΅λλ€."
}SetErrorHandlerλ₯Ό μ¬μ©νλ©΄ μ μ μ€λ₯ μ²λ¦¬ λ‘μ§μ μ§μ μ μν μ μμ΅λλ€. 컀μ€ν
HTML μ€λ₯ νμ΄μ§λ₯Ό λ λλ§νκ±°λ JSON ꡬ쑰λ₯Ό λ³κ²½νκ³ μΆμ λ μ μ©ν©λλ€.
package main
import (
"fmt"
"log"
"net/http"
"github.com/DevNewbie1826/httperror"
)
func main() {
// 컀μ€ν
μ μ μ€λ₯ νΈλ€λ¬ μ€μ
httperror.SetErrorHandler(func(w http.ResponseWriter, r *http.Request, err error) {
// νμνλ€λ©΄ νμ
λ¨μΈ(type assertion)μ ν΅ν΄ μν μ½λμ μ κ·Όν μ μμ΅λλ€.
status := http.StatusInternalServerError
message := "Internal Server Error"
if httpErr, ok := err.(*httperror.HttpError); ok {
status = httpErr.Status
message = httpErr.Message
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
fmt.Fprintf(w, `{"error": true, "code": %d, "msg": "%s"}`, status, message)
})
http.HandleFunc("/oops", func(w http.ResponseWriter, r *http.Request) {
httperror.BadRequest(w, r, "무μΈκ° μλͺ»λμμ΅λλ€!")
})
log.Println("Server starting on :8080")
http.ListenAndServe(":8080", nil)
}This project is licensed under the MIT License. See the LICENSE file for details.