You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中带错误码的多错误JSON格式返回处理问题

Solution for Accumulating Multiple Errors in Go

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:04:46