diff --git a/huma.go b/huma.go index 09aea2b2..1dc7a195 100644 --- a/huma.go +++ b/huma.go @@ -1379,6 +1379,13 @@ func Register[I, O any](api API, op Operation, handler func(context.Context, *I) return } + if output == nil { + // Special case: No err or output, so just set the status code and return. + // This is a weird case, but it's better than panicking or returning 500. + ctx.SetStatus(op.DefaultStatus) + return + } + // Serialize output headers ct := "" vo := reflect.ValueOf(output).Elem() diff --git a/huma_test.go b/huma_test.go index 3856dad8..9c24812d 100644 --- a/huma_test.go +++ b/huma_test.go @@ -1432,6 +1432,30 @@ Content of example2.txt. assert.JSONEq(t, `{"$schema": "https:///schemas/RespBody.json", "greeting":"Hello, world!"}`, resp.Body.String()) }, }, + { + Name: "response-nil", + Register: func(t *testing.T, api huma.API) { + type Resp struct { + Body struct { + Greeting string `json:"greeting"` + } + } + + huma.Register(api, huma.Operation{ + Method: http.MethodGet, + Path: "/response", + }, func(ctx context.Context, input *struct{}) (*Resp, error) { + return nil, nil + }) + }, + Method: http.MethodGet, + URL: "/response", + Assert: func(t *testing.T, resp *httptest.ResponseRecorder) { + // This should not panic and should return the default status code, + // which for responses which normally have a body is 200. + assert.Equal(t, http.StatusOK, resp.Code) + }, + }, { Name: "response-raw", Register: func(t *testing.T, api huma.API) {