README
¶
Microservice Error Definitions Example
This example shows how to use rescode in a microservice context with JSON format and different error categories.
errors.json
[
{
"code": 10001,
"key": "AuthenticationFailed",
"message": "Authentication failed",
"http": 401,
"grpc": 16,
"desc": "The provided credentials are invalid"
},
{
"code": 10002,
"key": "AuthorizationDenied",
"message": "Authorization denied",
"http": 403,
"grpc": 7,
"desc": "User does not have permission to perform this action"
},
{
"code": 20001,
"key": "PolicyNotFound",
"message": "Policy not found",
"http": 404,
"grpc": 5,
"desc": "Policy could not be located in the database"
},
{
"code": 20002,
"key": "InvalidPolicyKind",
"message": "Invalid policy kind",
"http": 400,
"grpc": 3,
"desc": "Policy kind is not supported"
},
{
"code": 30001,
"key": "RateLimitExceeded",
"message": "Rate limit exceeded",
"http": 429,
"grpc": 8,
"desc": "Request rate limit has been exceeded"
},
{
"code": 99999,
"key": "InternalServerError",
"message": "Internal server error",
"http": 500,
"grpc": 13,
"desc": "An unexpected internal error occurred"
}
]
service.go
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
)
//go:generate go run github.com/restayway/rescode/cmd/rescodegen --input errors.json --output service_errors.go --package main
type PolicyService struct{}
type Policy struct {
ID string `json:"id"`
Kind string `json:"kind"`
Name string `json:"name"`
}
func (s *PolicyService) GetPolicy(id string) (*Policy, error) {
// Simulate authentication check
if id == "unauthorized" {
return nil, AuthenticationFailed()
}
// Simulate authorization check
if id == "forbidden" {
return nil, AuthorizationDenied()
}
// Simulate policy not found
if id == "notfound" {
return nil, PolicyNotFound()
}
// Simulate invalid kind
if id == "invalid" {
originalErr := fmt.Errorf("unsupported kind: foobar")
return nil, InvalidPolicyKind(originalErr)
}
// Return a valid policy
return &Policy{
ID: id,
Kind: "standard",
Name: "Sample Policy",
}, nil
}
func handleError(w http.ResponseWriter, err error) {
if rcErr, ok := err.(*rescode.RC); ok {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(rcErr.HttpCode)
response := rcErr.JSON("code", "message", "data")
json.NewEncoder(w).Encode(response)
} else {
// Fallback for unknown errors
internalErr := InternalServerError(err)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(internalErr.HttpCode)
response := internalErr.JSON("code", "message")
json.NewEncoder(w).Encode(response)
}
}
func policyHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
err := InvalidPolicyKind().SetData(map[string]string{
"field": "id",
"reason": "missing required parameter",
})
handleError(w, err)
return
}
service := &PolicyService{}
policy, err := service.GetPolicy(id)
if err != nil {
handleError(w, err)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(policy)
}
func main() {
http.HandleFunc("/policy", policyHandler)
fmt.Println("Starting server on :8080")
fmt.Println("Try these URLs:")
fmt.Println(" http://localhost:8080/policy?id=123 (success)")
fmt.Println(" http://localhost:8080/policy?id=unauthorized (401)")
fmt.Println(" http://localhost:8080/policy?id=forbidden (403)")
fmt.Println(" http://localhost:8080/policy?id=notfound (404)")
fmt.Println(" http://localhost:8080/policy?id=invalid (400)")
fmt.Println(" http://localhost:8080/policy (400)")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Generate and Run
# Generate the error code
go generate
# Run the service
go run .
Example API Responses
Success (200)
curl "http://localhost:8080/policy?id=123"
{
"id": "123",
"kind": "standard",
"name": "Sample Policy"
}
Authentication Failed (401)
curl "http://localhost:8080/policy?id=unauthorized"
{
"code": 10001,
"message": "Authentication failed"
}
Authorization Denied (403)
curl "http://localhost:8080/policy?id=forbidden"
{
"code": 10002,
"message": "Authorization denied"
}
Policy Not Found (404)
curl "http://localhost:8080/policy?id=notfound"
{
"code": 20001,
"message": "Policy not found"
}
Invalid Policy Kind (400)
curl "http://localhost:8080/policy?id=invalid"
{
"code": 20002,
"message": "Invalid policy kind"
}
Benefits Demonstrated
- Type Safety: All error codes are compile-time constants
- Consistency: Standardized error response format
- HTTP Integration: Automatic HTTP status code mapping
- gRPC Ready: gRPC status codes included
- Additional Data: Structured error data support
- Error Wrapping: Original error preservation
- Performance: No runtime lookups or maps
Documentation
¶
There is no documentation for this package.
Click to show internal directories.
Click to hide internal directories.