Golang中带错误码的多错误JSON格式返回处理问题
Let's fix your error handling implementation so you can collect multiple errors and output the exact JSON format you need. First, let's break down what's wrong with your current code, then walk through the corrected approach.
Step 1: Define Proper Structs for JSON Serialization
First, let's make sure our structs match the JSON format you want. We'll use struct tags to control the JSON output, and mark ErrorField as optional with omitempty (since some errors like 500 don't need a field name):
package main import "encoding/json" // ErrorDetail represents a single error entry (either field-specific or general) type ErrorDetail struct { ErrorField string `json:"errorField,omitempty"` // Omit if empty ErrorDescription string `json:"errorDescription"` } // ErrorResponse is the top-level structure for your JSON error output type ErrorResponse struct { ErrorCode int `json:"errorCode"` Errors []ErrorDetail `json:"errors"` }
Step 2: Fix Error Accumulation Logic
Your current ErrorHandle function creates a new empty slice every time it's called, which is why previous errors get lost. Instead, we need a function that accepts the existing error collection, updates it, and returns the updated version.
Option 1: Support Multiple Error Codes (e.g., 400 and 500 in one response)
Use this if you need to return errors with different error codes in a single response:
// AddError takes an existing slice of ErrorResponse, adds a new error, and returns the updated slice func AddError(errResponses []ErrorResponse, code int, field, desc string) []ErrorResponse { // Check if we already have an ErrorResponse for this code for i, resp := range errResponses { if resp.ErrorCode == code { // Append the new error to the existing response's error list resp.Errors = append(resp.Errors, ErrorDetail{ ErrorField: field, ErrorDescription: desc, }) errResponses[i] = resp return errResponses } } // No existing response for this code? Create a new one newResp := ErrorResponse{ ErrorCode: code, Errors: []ErrorDetail{ { ErrorField: field, ErrorDescription: desc, }, }, } return append(errResponses, newResp) }
Usage Example:
func main() { // Start with an empty slice of error responses var errResponses []ErrorResponse // Add multiple errors (same or different codes) errResponses = AddError(errResponses, 400, "dispachNumber", "This is not a valid dispatch Number") errResponses = AddError(errResponses, 400, "phone", "Phone numbers must be in the XXX-XXX-XXXX format") errResponses = AddError(errResponses, 500, "", "there was an internal server error") // Marshal to JSON to verify the output jsonOutput, err := json.MarshalIndent(errResponses, "", " ") if err != nil { panic(err) } println(string(jsonOutput)) }
Option 2: Single Error Code (Most Common for HTTP Requests)
If you only need to return one error code per request (e.g., all validation errors are 400, server errors are 500), use a collector struct for cleaner code:
// ErrorCollector manages errors for a single error code type ErrorCollector struct { resp ErrorResponse } // NewErrorCollector creates a collector for a specific error code func NewErrorCollector(code int) *ErrorCollector { return &ErrorCollector{ resp: ErrorResponse{ ErrorCode: code, Errors: []ErrorDetail{}, }, } } // AddError adds a new error detail to the collector func (ec *ErrorCollector) AddError(field, desc string) { ec.resp.Errors = append(ec.resp.Errors, ErrorDetail{ ErrorField: field, ErrorDescription: desc, }) } // GetResponse returns the final ErrorResponse ready for JSON serialization func (ec *ErrorCollector) GetResponse() ErrorResponse { return ec.resp }
Usage Example:
func main() { // Create a collector for 400 errors collector := NewErrorCollector(400) collector.AddError("dispachNumber", "This is not a valid dispatch Number") collector.AddError("phone", "Phone numbers must be in the XXX-XXX-XXXX format") // Marshal the response to JSON jsonOutput, err := json.MarshalIndent(collector.GetResponse(), "", " ") if err != nil { panic(err) } println(string(jsonOutput)) }
Why Your Original Code Failed
The core issue was that every call to ErrorHandle initialized a new empty AllErrors slice:
AllErrors := []Errors{}
This meant any errors added in previous calls were completely discarded. Our fix ensures we pass the existing error collection into the function and update it, preserving all previous errors.
内容的提问来源于stack exchange,提问作者saddam

