fix: resolve correctness bugs and improve robustness#4
Open
cymoo wants to merge 1 commit into
Open
Conversation
Owner
cymoo
commented
May 7, 2026
- fix(path): replace concrete type switch with reflect.Kind so named type aliases (e.g. type UserID int) work correctly with Path[T]
- fix(path): normalize catch-all pattern keys by stripping trailing ... so /files/{path...} extracts via r.PathValue("path") as expected
- fix(result): write error status and JSON body code consistently when Result.Err is set; Result.Code is now used as the explicit override
- fix(headers): use setHeaderIfMissing so a Content-Type set in Result.Headers is not overwritten by automatic response handling
- fix(handler): validate unsupported parameter types at H() registration time instead of panicking on the first request
- fix(handler): allow Responder as a valid single-value interface return; allow http.Handler/io.Reader/Responder as first interface return in two-value signatures
- fix(writer): add Unwrap() to ResponseWriter for net/http compatibility with optional-interface discovery (e.g. http.NewResponseController)
- fix(config): lock mutex inside Initialize's sync.Once to be consistent with Configure/Reset; use logger() instead of log.Println for 5xx logs
- fix(validation): extend default tag name lookup order to json→schema→form so schema-tagged query/form fields appear correctly in error messages
- test: add targeted tests for each of the above issues
- fix(path): replace concrete type switch with reflect.Kind so named
type aliases (e.g. type UserID int) work correctly with Path[T]
- fix(path): normalize catch-all pattern keys by stripping trailing ...
so /files/{path...} extracts via r.PathValue("path") as expected
- fix(result): write error status and JSON body code consistently when
Result.Err is set; Result.Code is now used as the explicit override
- fix(headers): use setHeaderIfMissing so a Content-Type set in
Result.Headers is not overwritten by automatic response handling
- fix(handler): validate unsupported parameter types at H() registration
time instead of panicking on the first request
- fix(handler): allow Responder as a valid single-value interface return;
allow http.Handler/io.Reader/Responder as first interface return in
two-value signatures
- fix(writer): add Unwrap() to ResponseWriter for net/http compatibility
with optional-interface discovery (e.g. http.NewResponseController)
- fix(config): lock mutex inside Initialize's sync.Once to be consistent
with Configure/Reset; use logger() instead of log.Println for 5xx logs
- fix(validation): extend default tag name lookup order to json→schema→form
so schema-tagged query/form fields appear correctly in error messages
- test: add targeted tests for each of the above issues
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR tightens Mint’s request/response correctness and robustness, primarily around handler signature validation, path param extraction, response header/error handling, and config/validation defaults, with targeted tests added to lock in behavior.
Changes:
- Fixes
Path[T]extraction for named underlying types and catch-all ({name...}) patterns. - Makes response writing more consistent (error code/body alignment; don’t overwrite user-provided
Content-Type; addResponseWriter.Unwrap). - Validates handler signatures/parameter types earlier in
H(...)and expands allowed interface return types; extends validator tag-name resolution tojson → schema → form.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
README.md |
Updates documented default validator tag-name behavior to include schema. |
mint.go |
Core fixes across path extraction, handler validation, response writing/error handling, config locking, and validation tag lookup. |
mint_test.go |
Adds regression tests covering the fixed behaviors (Path aliases/catch-all, Result error consistency, content-type preservation, Unwrap, schema tag naming, etc.). |
.github/copilot-instructions.md |
Adds repo-specific developer guidance and commands (needs alignment with updated behavior). |
Comments suppressed due to low confidence (1)
mint.go:534
- The new
fn == nilguard only catches a nil interface. If the caller passes a typed-nil function value (e.g.var f func(...)=nil; H(f)),reflect.ValueOfsucceeds but the first request will panic when calling the nil function. Consider also checkingfnVal.Kind() == reflect.Func && fnVal.IsNil()and panicking early with a clear message.
func H(fn any) http.HandlerFunc {
if fn == nil {
log.Panic("H: handler must be a function, got <nil>")
}
fnVal := reflect.ValueOf(fn)
fnType := fnVal.Type()
if fnType.Kind() != reflect.Func {
log.Panicf("H: handler must be a function, got %T", fn)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+562
to
+563
| if rt1.Kind() == reflect.Interface && !isSupportedDataInterfaceReturn(rt1) { | ||
| log.Panic("H: first return interface must implement http.Handler, io.Reader or Responder") |
|
|
||
| ## Key conventions | ||
|
|
||
| - Handler functions passed to `H` may return zero, one, or two values only. Two-value returns must be `(non-interface, error)`, and the first return value cannot be `Result[T]`. |
| ## Key conventions | ||
|
|
||
| - Handler functions passed to `H` may return zero, one, or two values only. Two-value returns must be `(non-interface, error)`, and the first return value cannot be `Result[T]`. | ||
| - Handler parameters are limited to built-in/custom extractors, `http.ResponseWriter`, and `*http.Request`; unsupported parameter types panic during request handling. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.