feat: typed 400 validation errors with stable reason codes

Invalid limit/start/boolean params now return 400 bad_request with a
machine-readable reason field (INVALID_LIMIT, INVALID_START,
INVALID_PARAM, EMPTY_QUERY) instead of 500. Limit is validated in
range [1, 100].
This commit is contained in:
Rustem Kamalov
2026-04-24 05:14:18 +03:00
parent 0ccb13c36e
commit 6992ad585d
5 changed files with 101 additions and 22 deletions

40
core/errors.go Normal file
View File

@@ -0,0 +1,40 @@
package core
import "fmt"
// APIError represents a client-facing error with a stable machine-readable reason code.
type APIError struct {
HTTPStatus int
Reason string
Message string
}
func (e *APIError) Error() string {
return fmt.Sprintf("%s: %s", e.Reason, e.Message)
}
// Common validation reason codes.
const (
ReasonInvalidLimit = "INVALID_LIMIT"
ReasonInvalidStart = "INVALID_START"
ReasonInvalidParam = "INVALID_PARAM"
ReasonEmptyQuery = "EMPTY_QUERY"
ReasonNoEngines = "NO_ENGINES"
ReasonUnknownFormat = "UNKNOWN_FORMAT"
)
func errInvalidLimit(msg string) *APIError {
return &APIError{HTTPStatus: 400, Reason: ReasonInvalidLimit, Message: msg}
}
func errInvalidStart(msg string) *APIError {
return &APIError{HTTPStatus: 400, Reason: ReasonInvalidStart, Message: msg}
}
func errInvalidParam(msg string) *APIError {
return &APIError{HTTPStatus: 400, Reason: ReasonInvalidParam, Message: msg}
}
func errEmptyQuery() *APIError {
return &APIError{HTTPStatus: 400, Reason: ReasonEmptyQuery, Message: "query cannot be empty: provide text, site, or file parameter"}
}