Compare commits

...

1 Commits

Author SHA1 Message Date
dependabot[bot]
e8c330b736 build(deps): bump github.com/go-openapi/errors in /src/runtime
Bumps [github.com/go-openapi/errors](https://github.com/go-openapi/errors) from 0.22.1 to 0.22.7.
- [Release notes](https://github.com/go-openapi/errors/releases)
- [Commits](https://github.com/go-openapi/errors/compare/v0.22.1...v0.22.7)

---
updated-dependencies:
- dependency-name: github.com/go-openapi/errors
  dependency-version: 0.22.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 14:29:20 +00:00
17 changed files with 512 additions and 315 deletions

View File

@@ -26,7 +26,7 @@ require (
github.com/docker/go-units v0.5.0
github.com/fsnotify/fsnotify v1.9.0
github.com/go-ini/ini v1.67.0
github.com/go-openapi/errors v0.22.1
github.com/go-openapi/errors v0.22.7
github.com/go-openapi/runtime v0.28.0
github.com/go-openapi/strfmt v0.23.0
github.com/go-openapi/swag v0.23.1

View File

@@ -107,8 +107,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU=
github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=
github.com/go-openapi/errors v0.22.7 h1:JLFBGC0Apwdzw3484MmBqspjPbwa2SHvpDm0u5aGhUA=
github.com/go-openapi/errors v0.22.7/go.mod h1://QW6SD9OsWtH6gHllUCddOXDL0tk0ZGNYHwsw4sW3w=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
@@ -123,6 +123,8 @@ github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMg
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
github.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM=
github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=

View File

@@ -0,0 +1,26 @@
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
# Set default charset
[*.{js,py,go,scala,rb,java,html,css,less,sass,md}]
charset = utf-8
# Tab indentation (no size specified)
[*.go]
indent_style = tab
[*.md]
trim_trailing_whitespace = false
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

View File

@@ -1,2 +1,7 @@
secrets.yml
coverage.out
*.out
*.cov
.idea
.env
.mcp.json
.claude/
settings.local.json

View File

@@ -1,55 +1,71 @@
linters-settings:
gocyclo:
min-complexity: 45
dupl:
threshold: 200
goconst:
min-len: 2
min-occurrences: 3
version: "2"
linters:
enable-all: true
default: all
disable:
- unparam
- lll
- gochecknoinits
- gochecknoglobals
- depguard
- funlen
- godox
- gocognit
- whitespace
- wsl
- wrapcheck
- testpackage
- nlreturn
- errorlint
- nestif
- godot
- gofumpt
- paralleltest
- tparallel
- thelper
- exhaustruct
- varnamelen
- gci
- depguard
- errchkjson
- inamedparam
- nlreturn
- nonamedreturns
- musttag
- ireturn
- forcetypeassert
- cyclop
# deprecated linters
#- deadcode
#- interfacer
#- scopelint
#- varcheck
#- structcheck
#- golint
#- nosnakecase
#- maligned
#- goerr113
#- ifshort
#- gomnd
#- exhaustivestruct
- noinlineerr
- paralleltest
- recvcheck
- testpackage
- thelper
- tparallel
- varnamelen
- whitespace
- wrapcheck
- wsl
- wsl_v5
settings:
dupl:
threshold: 200
goconst:
min-len: 2
min-occurrences: 3
cyclop:
max-complexity: 20
gocyclo:
min-complexity: 20
exhaustive:
default-signifies-exhaustive: true
default-case-required: true
lll:
line-length: 180
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- revive
text: "avoid package names that conflict with Go standard library package names"
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gofmt
- goimports
- gofumpt
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
issues:
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
max-issues-per-linter: 0
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
max-same-issues: 0

View File

@@ -23,7 +23,9 @@ include:
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
@@ -55,7 +57,7 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ivan+abuse@flanders.co.nz. All
reported by contacting the project team at <ivan+abuse@flanders.co.nz>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
@@ -68,7 +70,7 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
available at [<http://contributor-covenant.org/version/1/4>][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -0,0 +1,25 @@
# Contributors
- Repository: ['go-openapi/errors']
| Total Contributors | Total Contributions |
| --- | --- |
| 13 | 110 |
| Username | All Time Contribution Count | All Commits |
| --- | --- | --- |
| @casualjim | 58 | <https://github.com/go-openapi/errors/commits?author=casualjim> |
| @fredbi | 36 | <https://github.com/go-openapi/errors/commits?author=fredbi> |
| @youyuanwu | 5 | <https://github.com/go-openapi/errors/commits?author=youyuanwu> |
| @alexandear | 2 | <https://github.com/go-openapi/errors/commits?author=alexandear> |
| @fiorix | 1 | <https://github.com/go-openapi/errors/commits?author=fiorix> |
| @ligustah | 1 | <https://github.com/go-openapi/errors/commits?author=ligustah> |
| @artemseleznev | 1 | <https://github.com/go-openapi/errors/commits?author=artemseleznev> |
| @gautierdelorme | 1 | <https://github.com/go-openapi/errors/commits?author=gautierdelorme> |
| @guillemj | 1 | <https://github.com/go-openapi/errors/commits?author=guillemj> |
| @maxatome | 1 | <https://github.com/go-openapi/errors/commits?author=maxatome> |
| @Simon-Li | 1 | <https://github.com/go-openapi/errors/commits?author=Simon-Li> |
| @aokumasan | 1 | <https://github.com/go-openapi/errors/commits?author=aokumasan> |
| @ujjwalsh | 1 | <https://github.com/go-openapi/errors/commits?author=ujjwalsh> |
_this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_

View File

@@ -1,8 +1,118 @@
# OpenAPI errors [![Build Status](https://github.com/go-openapi/errors/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/errors/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/errors)
# errors
[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE)
[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/errors.svg)](https://pkg.go.dev/github.com/go-openapi/errors)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/errors)](https://goreportcard.com/report/github.com/go-openapi/errors)
<!-- Badges: status -->
[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url]
<!-- Badges: release & docker images -->
<!-- Badges: code quality -->
<!-- Badges: license & compliance -->
[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url]
<!-- Badges: documentation & support -->
<!-- Badges: others & stats -->
[![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge]
---
Shared errors and error interface used throughout the various libraries found in the go-openapi toolkit.
## Announcements
* **2025-12-19** : new community chat on discord
* a new discord community channel is available to be notified of changes and support users
* our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31**
You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url]
Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url]
## Status
API is stable.
## Import this library in your project
```cmd
go get github.com/go-openapi/errors
```
## Basic usage
```go
const url = "https://www.example.com/#"
errGeneric := New(401,"onvalid argument: %s", url)
errNotFound := NotFound("resource not found: %s", url)
errNotImplemented := NotImplemented("method: %s", url)
```
## Change log
See <https://github.com/go-openapi/errors/releases>
<!--
## References
-->
## Licensing
This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE).
<!--
## Limitations
-->
## Other documentation
* [All-time contributors](./CONTRIBUTORS.md)
* [Contributing guidelines](.github/CONTRIBUTING.md)
* [Maintainers documentation](docs/MAINTAINERS.md)
* [Code style](docs/STYLE.md)
## Cutting a new release
Maintainers can cut a new release by either:
* running [this workflow](https://github.com/go-openapi/errors/actions/workflows/bump-release.yml)
* or pushing a semver tag
* signed tags are preferred
* The tag message is prepended to release notes
<!-- Badges: status -->
[test-badge]: https://github.com/go-openapi/errors/actions/workflows/go-test.yml/badge.svg
[test-url]: https://github.com/go-openapi/errors/actions/workflows/go-test.yml
[cov-badge]: https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg
[cov-url]: https://codecov.io/gh/go-openapi/errors
[vuln-scan-badge]: https://github.com/go-openapi/errors/actions/workflows/scanner.yml/badge.svg
[vuln-scan-url]: https://github.com/go-openapi/errors/actions/workflows/scanner.yml
[codeql-badge]: https://github.com/go-openapi/errors/actions/workflows/codeql.yml/badge.svg
[codeql-url]: https://github.com/go-openapi/errors/actions/workflows/codeql.yml
<!-- Badges: release & docker images -->
[release-badge]: https://badge.fury.io/gh/go-openapi%2Ferrors.svg
[release-url]: https://badge.fury.io/gh/go-openapi%2Ferrors
<!-- Badges: code quality -->
[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/errors
[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/errors
[codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/errors
[codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/errors
<!-- Badges: documentation & support -->
[godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/errors
[godoc-url]: http://pkg.go.dev/github.com/go-openapi/errors
[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png
[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM
[slack-url]: https://goswagger.slack.com/archives/C04R30YMU
[discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue
[discord-url]: https://discord.gg/twZ9BwT3
<!-- Badges: license & compliance -->
[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg
[license-url]: https://github.com/go-openapi/errors/?tab=Apache-2.0-1-ov-file#readme
<!-- Badges: others & stats -->
[goversion-badge]: https://img.shields.io/github/go-mod/go-version/go-openapi/errors
[goversion-url]: https://github.com/go-openapi/errors/blob/master/go.mod
[top-badge]: https://img.shields.io/github/languages/top/go-openapi/errors
[commits-badge]: https://img.shields.io/github/commits-since/go-openapi/errors/latest

View File

@@ -0,0 +1,37 @@
# Security Policy
This policy outlines the commitment and practices of the go-openapi maintainers regarding security.
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 0.x | :white_check_mark: |
## Vulnerability checks in place
This repository uses automated vulnerability scans, at every merged commit and at least once a week.
We use:
* [`GitHub CodeQL`][codeql-url]
* [`trivy`][trivy-url]
* [`govulncheck`][govulncheck-url]
Reports are centralized in github security reports and visible only to the maintainers.
## Reporting a vulnerability
If you become aware of a security vulnerability that affects the current repository,
**please report it privately to the maintainers**
rather than opening a publicly visible GitHub issue.
Please follow the instructions provided by github to [Privately report a security vulnerability][github-guidance-url].
> [!NOTE]
> On Github, navigate to the project's "Security" tab then click on "Report a vulnerability".
[codeql-url]: https://github.com/github/codeql
[trivy-url]: https://trivy.dev/docs/latest/getting-started
[govulncheck-url]: https://go.dev/blog/govulncheck
[github-guidance-url]: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability

View File

@@ -1,21 +1,11 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package errors
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"reflect"
@@ -23,9 +13,11 @@ import (
)
// DefaultHTTPCode is used when the error Code cannot be used as an HTTP code.
//
//nolint:gochecknoglobals // it should have been a constant in the first place, but now it is mutable so we have to leave it here or introduce a breaking change.
var DefaultHTTPCode = http.StatusUnprocessableEntity
// Error represents a error interface all swagger framework errors implement
// Error represents a error interface all swagger framework errors implement.
type Error interface {
error
Code() int32
@@ -36,24 +28,26 @@ type apiError struct {
message string
}
// Error implements the standard error interface.
func (a *apiError) Error() string {
return a.message
}
// Code returns the HTTP status code associated with this error.
func (a *apiError) Code() int32 {
return a.code
}
// MarshalJSON implements the JSON encoding interface
// MarshalJSON implements the JSON encoding interface.
func (a apiError) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"code": a.code,
"message": a.message,
})
}
// New creates a new API error with a code and a message
func New(code int32, message string, args ...interface{}) Error {
// New creates a new API error with a code and a message.
func New(code int32, message string, args ...any) Error {
if len(args) > 0 {
return &apiError{
code: code,
@@ -66,38 +60,39 @@ func New(code int32, message string, args ...interface{}) Error {
}
}
// NotFound creates a new not found error
func NotFound(message string, args ...interface{}) Error {
// NotFound creates a new not found error.
func NotFound(message string, args ...any) Error {
if message == "" {
message = "Not found"
}
return New(http.StatusNotFound, fmt.Sprintf(message, args...))
return New(http.StatusNotFound, message, args...)
}
// NotImplemented creates a new not implemented error
// NotImplemented creates a new not implemented error.
func NotImplemented(message string) Error {
return New(http.StatusNotImplemented, message)
return New(http.StatusNotImplemented, "%s", message)
}
// MethodNotAllowedError represents an error for when the path matches but the method doesn't
// MethodNotAllowedError represents an error for when the path matches but the method doesn't.
type MethodNotAllowedError struct {
code int32
Allowed []string
message string
}
// Error implements the standard error interface.
func (m *MethodNotAllowedError) Error() string {
return m.message
}
// Code the error code
// Code returns 405 (Method Not Allowed) as the HTTP status code.
func (m *MethodNotAllowedError) Code() int32 {
return m.code
}
// MarshalJSON implements the JSON encoding interface
// MarshalJSON implements the JSON encoding interface.
func (m MethodNotAllowedError) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"code": m.code,
"message": m.message,
"allowed": m.Allowed,
@@ -115,25 +110,33 @@ func errorAsJSON(err Error) []byte {
func flattenComposite(errs *CompositeError) *CompositeError {
var res []error
for _, er := range errs.Errors {
switch e := er.(type) {
case *CompositeError:
if e != nil && len(e.Errors) > 0 {
flat := flattenComposite(e)
if len(flat.Errors) > 0 {
res = append(res, flat.Errors...)
}
}
default:
if e != nil {
res = append(res, e)
}
for _, err := range errs.Errors {
if err == nil {
continue
}
e := &CompositeError{}
if !errors.As(err, &e) {
res = append(res, err)
continue
}
if len(e.Errors) == 0 {
res = append(res, e)
continue
}
flat := flattenComposite(e)
res = append(res, flat.Errors...)
}
return CompositeValidationError(res...)
}
// MethodNotAllowed creates a new method not allowed error
// MethodNotAllowed creates a new method not allowed error.
func MethodNotAllowed(requested string, allow []string) Error {
msg := fmt.Sprintf("method %s is not allowed, but [%s] are", requested, strings.Join(allow, ","))
return &MethodNotAllowedError{
@@ -143,43 +146,59 @@ func MethodNotAllowed(requested string, allow []string) Error {
}
}
// ServeError implements the http error handler interface
// ServeError implements the [http] error handler interface.
func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
rw.Header().Set("Content-Type", "application/json")
switch e := err.(type) {
case *CompositeError:
er := flattenComposite(e)
if err == nil {
rw.WriteHeader(http.StatusInternalServerError)
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
return
}
errComposite := &CompositeError{}
errMethodNotAllowed := &MethodNotAllowedError{}
var errError Error
switch {
case errors.As(err, &errComposite):
er := flattenComposite(errComposite)
// strips composite errors to first element only
if len(er.Errors) > 0 {
ServeError(rw, r, er.Errors[0])
} else {
// guard against empty CompositeError (invalid construct)
ServeError(rw, r, nil)
return
}
case *MethodNotAllowedError:
rw.Header().Add("Allow", strings.Join(e.Allowed, ","))
rw.WriteHeader(asHTTPCode(int(e.Code())))
// guard against empty CompositeError (invalid construct)
ServeError(rw, r, nil)
case errors.As(err, &errMethodNotAllowed):
rw.Header().Add("Allow", strings.Join(errMethodNotAllowed.Allowed, ","))
rw.WriteHeader(asHTTPCode(int(errMethodNotAllowed.Code())))
if r == nil || r.Method != http.MethodHead {
_, _ = rw.Write(errorAsJSON(e))
_, _ = rw.Write(errorAsJSON(errMethodNotAllowed))
}
case Error:
value := reflect.ValueOf(e)
case errors.As(err, &errError):
value := reflect.ValueOf(errError)
if value.Kind() == reflect.Ptr && value.IsNil() {
rw.WriteHeader(http.StatusInternalServerError)
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
return
}
rw.WriteHeader(asHTTPCode(int(e.Code())))
rw.WriteHeader(asHTTPCode(int(errError.Code())))
if r == nil || r.Method != http.MethodHead {
_, _ = rw.Write(errorAsJSON(e))
_, _ = rw.Write(errorAsJSON(errError))
}
case nil:
rw.WriteHeader(http.StatusInternalServerError)
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
default:
rw.WriteHeader(http.StatusInternalServerError)
if r == nil || r.Method != http.MethodHead {
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, err.Error())))
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "%v", err)))
}
}
}

View File

@@ -1,22 +1,11 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package errors
import "net/http"
// Unauthenticated returns an unauthenticated error
// Unauthenticated returns an unauthenticated error.
func Unauthenticated(scheme string) Error {
return New(http.StatusUnauthorized, "unauthenticated for %s", scheme)
}

View File

@@ -1,26 +1,13 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
/*
Package errors provides an Error interface and several concrete types
implementing this interface to manage API errors and JSON-schema validation
errors.
A middleware handler ServeError() is provided to serve the errors types
it defines.
It is used throughout the various go-openapi toolkit libraries
(https://github.com/go-openapi).
*/
// Package errors provides an Error interface and several concrete types
// implementing this interface to manage API errors and JSON-schema validation
// errors.
//
// A middleware handler [ServeError]() is provided to serve the errors types
// it defines.
//
// It is used throughout the various go-openapi toolkit libraries.
// (https://github.com/go-openapi).
package errors

View File

@@ -1,16 +1,5 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package errors
@@ -20,28 +9,30 @@ import (
"net/http"
)
// Validation represents a failure of a precondition
type Validation struct { //nolint: errname
// Validation represents a failure of a precondition.
type Validation struct { //nolint: errname // changing the name to abide by the naming rule would bring a breaking change.
code int32
Name string
In string
Value interface{}
Value any
message string
Values []interface{}
Values []any
}
// Error implements the standard error interface.
func (e *Validation) Error() string {
return e.message
}
// Code the error code
// Code returns the HTTP status code for this validation error.
// Returns 422 (Unprocessable Entity) by default.
func (e *Validation) Code() int32 {
return e.code
}
// MarshalJSON implements the JSON encoding interface
// MarshalJSON implements the JSON encoding interface.
func (e Validation) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"code": e.code,
"message": e.message,
"in": e.In,
@@ -51,7 +42,7 @@ func (e Validation) MarshalJSON() ([]byte, error) {
})
}
// ValidateName sets the name for a validation or updates it for a nested property
// ValidateName sets the name for a validation or updates it for a nested property.
func (e *Validation) ValidateName(name string) *Validation {
if name != "" {
if e.Name == "" {
@@ -70,9 +61,9 @@ const (
responseFormatFail = `unsupported media type requested, only %v are available`
)
// InvalidContentType error for an invalid content type
// InvalidContentType error for an invalid content type.
func InvalidContentType(value string, allowed []string) *Validation {
values := make([]interface{}, 0, len(allowed))
values := make([]any, 0, len(allowed))
for _, v := range allowed {
values = append(values, v)
}
@@ -86,9 +77,9 @@ func InvalidContentType(value string, allowed []string) *Validation {
}
}
// InvalidResponseFormat error for an unacceptable response format request
// InvalidResponseFormat error for an unacceptable response format request.
func InvalidResponseFormat(value string, allowed []string) *Validation {
values := make([]interface{}, 0, len(allowed))
values := make([]any, 0, len(allowed))
for _, v := range allowed {
values = append(values, v)
}

View File

@@ -1,16 +1,5 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package errors
@@ -21,13 +10,14 @@ import (
)
// APIVerificationFailed is an error that contains all the missing info for a mismatched section
// between the api registrations and the api spec
// between the api registrations and the api spec.
type APIVerificationFailed struct { //nolint: errname
Section string `json:"section,omitempty"`
MissingSpecification []string `json:"missingSpecification,omitempty"`
MissingRegistration []string `json:"missingRegistration,omitempty"`
}
// Error implements the standard error interface.
func (v *APIVerificationFailed) Error() string {
buf := bytes.NewBuffer(nil)
@@ -35,7 +25,7 @@ func (v *APIVerificationFailed) Error() string {
hasSpecMissing := len(v.MissingSpecification) > 0
if hasRegMissing {
buf.WriteString(fmt.Sprintf("missing [%s] %s registrations", strings.Join(v.MissingRegistration, ", "), v.Section))
fmt.Fprintf(buf, "missing [%s] %s registrations", strings.Join(v.MissingRegistration, ", "), v.Section)
}
if hasRegMissing && hasSpecMissing {
@@ -43,7 +33,7 @@ func (v *APIVerificationFailed) Error() string {
}
if hasSpecMissing {
buf.WriteString(fmt.Sprintf("missing from spec file [%s] %s", strings.Join(v.MissingSpecification, ", "), v.Section))
fmt.Fprintf(buf, "missing from spec file [%s] %s", strings.Join(v.MissingSpecification, ", "), v.Section)
}
return buf.String()

View File

@@ -1,16 +1,5 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package errors
@@ -20,7 +9,7 @@ import (
"net/http"
)
// ParseError represents a parsing error
// ParseError represents a parsing error.
type ParseError struct {
code int32
Name string
@@ -30,37 +19,7 @@ type ParseError struct {
message string
}
func (e *ParseError) Error() string {
return e.message
}
// Code returns the http status code for this error
func (e *ParseError) Code() int32 {
return e.code
}
// MarshalJSON implements the JSON encoding interface
func (e ParseError) MarshalJSON() ([]byte, error) {
var reason string
if e.Reason != nil {
reason = e.Reason.Error()
}
return json.Marshal(map[string]interface{}{
"code": e.code,
"message": e.message,
"in": e.In,
"name": e.Name,
"value": e.Value,
"reason": reason,
})
}
const (
parseErrorTemplContent = `parsing %s %s from %q failed, because %s`
parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s`
)
// NewParseError creates a new parse error
// NewParseError creates a new parse error.
func NewParseError(name, in, value string, reason error) *ParseError {
var msg string
if in == "" {
@@ -77,3 +36,34 @@ func NewParseError(name, in, value string, reason error) *ParseError {
message: msg,
}
}
// Error implements the standard error interface.
func (e *ParseError) Error() string {
return e.message
}
// Code returns 400 (Bad Request) as the HTTP status code for parsing errors.
func (e *ParseError) Code() int32 {
return e.code
}
// MarshalJSON implements the JSON encoding interface.
func (e ParseError) MarshalJSON() ([]byte, error) {
var reason string
if e.Reason != nil {
reason = e.Reason.Error()
}
return json.Marshal(map[string]any{
"code": e.code,
"message": e.message,
"in": e.In,
"name": e.Name,
"value": e.Value,
"reason": reason,
})
}
const (
parseErrorTemplContent = `parsing %s %s from %q failed, because %s`
parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s`
)

View File

@@ -1,21 +1,11 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package errors
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
@@ -73,14 +63,15 @@ const (
const maximumValidHTTPCode = 600
// All code responses can be used to differentiate errors for different handling
// by the consuming program
// by the consuming program.
const (
// CompositeErrorCode remains 422 for backwards-compatibility
// and to separate it from validation errors with cause
// and to separate it from validation errors with cause.
CompositeErrorCode = http.StatusUnprocessableEntity
// InvalidTypeCode is used for any subclass of invalid types
// InvalidTypeCode is used for any subclass of invalid types.
InvalidTypeCode = maximumValidHTTPCode + iota
// RequiredFailCode indicates a required field is missing.
RequiredFailCode
TooLongFailCode
TooShortFailCode
@@ -101,22 +92,26 @@ const (
ReadOnlyFailCode
)
// CompositeError is an error that groups several errors together
// CompositeError is an error that groups several errors together.
type CompositeError struct {
Errors []error
code int32
message string
}
// Code for this error
// Code returns the HTTP status code for this composite error.
func (c *CompositeError) Code() int32 {
return c.code
}
// Error implements the standard error interface.
func (c *CompositeError) Error() string {
if len(c.Errors) > 0 {
msgs := []string{c.message + ":"}
for _, e := range c.Errors {
if e == nil {
continue
}
msgs = append(msgs, e.Error())
}
return strings.Join(msgs, "\n")
@@ -124,20 +119,21 @@ func (c *CompositeError) Error() string {
return c.message
}
// Unwrap implements the [errors.Unwrap] interface.
func (c *CompositeError) Unwrap() []error {
return c.Errors
}
// MarshalJSON implements the JSON encoding interface
// MarshalJSON implements the JSON encoding interface.
func (c CompositeError) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
return json.Marshal(map[string]any{
"code": c.code,
"message": c.message,
"errors": c.Errors,
})
}
// CompositeValidationError an error to wrap a bunch of other errors
// CompositeValidationError an error to wrap a bunch of other errors.
func CompositeValidationError(errors ...error) *CompositeError {
return &CompositeError{
code: CompositeErrorCode,
@@ -146,20 +142,33 @@ func CompositeValidationError(errors ...error) *CompositeError {
}
}
// ValidateName recursively sets the name for all validations or updates them for nested properties
// ValidateName recursively sets the name for all validations or updates them for nested properties.
func (c *CompositeError) ValidateName(name string) *CompositeError {
for i, e := range c.Errors {
if ve, ok := e.(*Validation); ok {
c.Errors[i] = ve.ValidateName(name)
} else if ce, ok := e.(*CompositeError); ok {
c.Errors[i] = ce.ValidateName(name)
if e == nil {
continue
}
ce := &CompositeError{}
if errors.As(e, &ce) {
c.Errors[i] = ce.ValidateName(name)
continue
}
ve := &Validation{}
if errors.As(e, &ve) {
c.Errors[i] = ve.ValidateName(name)
continue
}
}
return c
}
// FailedAllPatternProperties an error for when the property doesn't match a pattern
// FailedAllPatternProperties an error for when the property doesn't match a pattern.
func FailedAllPatternProperties(name, in, key string) *Validation {
msg := fmt.Sprintf(failedAllPatternProps, name, key, in)
if in == "" {
@@ -174,7 +183,7 @@ func FailedAllPatternProperties(name, in, key string) *Validation {
}
}
// PropertyNotAllowed an error for when the property doesn't match a pattern
// PropertyNotAllowed an error for when the property doesn't match a pattern.
func PropertyNotAllowed(name, in, key string) *Validation {
msg := fmt.Sprintf(unallowedProperty, name, key, in)
if in == "" {
@@ -189,7 +198,7 @@ func PropertyNotAllowed(name, in, key string) *Validation {
}
}
// TooFewProperties an error for an object with too few properties
// TooFewProperties an error for an object with too few properties.
func TooFewProperties(name, in string, n int64) *Validation {
msg := fmt.Sprintf(tooFewProperties, name, in, n)
if in == "" {
@@ -204,7 +213,7 @@ func TooFewProperties(name, in string, n int64) *Validation {
}
}
// TooManyProperties an error for an object with too many properties
// TooManyProperties an error for an object with too many properties.
func TooManyProperties(name, in string, n int64) *Validation {
msg := fmt.Sprintf(tooManyProperties, name, in, n)
if in == "" {
@@ -219,7 +228,7 @@ func TooManyProperties(name, in string, n int64) *Validation {
}
}
// AdditionalItemsNotAllowed an error for invalid additional items
// AdditionalItemsNotAllowed an error for invalid additional items.
func AdditionalItemsNotAllowed(name, in string) *Validation {
msg := fmt.Sprintf(noAdditionalItems, name, in)
if in == "" {
@@ -233,7 +242,7 @@ func AdditionalItemsNotAllowed(name, in string) *Validation {
}
}
// InvalidCollectionFormat another flavor of invalid type error
// InvalidCollectionFormat another flavor of invalid type error.
func InvalidCollectionFormat(name, in, format string) *Validation {
return &Validation{
code: InvalidTypeCode,
@@ -244,7 +253,7 @@ func InvalidCollectionFormat(name, in, format string) *Validation {
}
}
// InvalidTypeName an error for when the type is invalid
// InvalidTypeName an error for when the type is invalid.
func InvalidTypeName(typeName string) *Validation {
return &Validation{
code: InvalidTypeCode,
@@ -253,8 +262,8 @@ func InvalidTypeName(typeName string) *Validation {
}
}
// InvalidType creates an error for when the type is invalid
func InvalidType(name, in, typeName string, value interface{}) *Validation {
// InvalidType creates an error for when the type is invalid.
func InvalidType(name, in, typeName string, value any) *Validation {
var message string
if in != "" {
@@ -284,10 +293,9 @@ func InvalidType(name, in, typeName string, value interface{}) *Validation {
Value: value,
message: message,
}
}
// DuplicateItems error for when an array contains duplicates
// DuplicateItems error for when an array contains duplicates.
func DuplicateItems(name, in string) *Validation {
msg := fmt.Sprintf(uniqueFail, name, in)
if in == "" {
@@ -301,8 +309,8 @@ func DuplicateItems(name, in string) *Validation {
}
}
// TooManyItems error for when an array contains too many items
func TooManyItems(name, in string, maximum int64, value interface{}) *Validation {
// TooManyItems error for when an array contains too many items.
func TooManyItems(name, in string, maximum int64, value any) *Validation {
msg := fmt.Sprintf(maximumItemsFail, name, in, maximum)
if in == "" {
msg = fmt.Sprintf(maximumItemsFailNoIn, name, maximum)
@@ -317,8 +325,8 @@ func TooManyItems(name, in string, maximum int64, value interface{}) *Validation
}
}
// TooFewItems error for when an array contains too few items
func TooFewItems(name, in string, minimum int64, value interface{}) *Validation {
// TooFewItems error for when an array contains too few items.
func TooFewItems(name, in string, minimum int64, value any) *Validation {
msg := fmt.Sprintf(minItemsFail, name, in, minimum)
if in == "" {
msg = fmt.Sprintf(minItemsFailNoIn, name, minimum)
@@ -332,8 +340,8 @@ func TooFewItems(name, in string, minimum int64, value interface{}) *Validation
}
}
// ExceedsMaximumInt error for when maximumimum validation fails
func ExceedsMaximumInt(name, in string, maximum int64, exclusive bool, value interface{}) *Validation {
// ExceedsMaximumInt error for when maximum validation fails.
func ExceedsMaximumInt(name, in string, maximum int64, exclusive bool, value any) *Validation {
var message string
if in == "" {
m := maximumIncFailNoIn
@@ -357,8 +365,8 @@ func ExceedsMaximumInt(name, in string, maximum int64, exclusive bool, value int
}
}
// ExceedsMaximumUint error for when maximumimum validation fails
func ExceedsMaximumUint(name, in string, maximum uint64, exclusive bool, value interface{}) *Validation {
// ExceedsMaximumUint error for when maximum validation fails.
func ExceedsMaximumUint(name, in string, maximum uint64, exclusive bool, value any) *Validation {
var message string
if in == "" {
m := maximumIncFailNoIn
@@ -382,8 +390,8 @@ func ExceedsMaximumUint(name, in string, maximum uint64, exclusive bool, value i
}
}
// ExceedsMaximum error for when maximumimum validation fails
func ExceedsMaximum(name, in string, maximum float64, exclusive bool, value interface{}) *Validation {
// ExceedsMaximum error for when maximum validation fails.
func ExceedsMaximum(name, in string, maximum float64, exclusive bool, value any) *Validation {
var message string
if in == "" {
m := maximumIncFailNoIn
@@ -407,8 +415,8 @@ func ExceedsMaximum(name, in string, maximum float64, exclusive bool, value inte
}
}
// ExceedsMinimumInt error for when minimum validation fails
func ExceedsMinimumInt(name, in string, minimum int64, exclusive bool, value interface{}) *Validation {
// ExceedsMinimumInt error for when minimum validation fails.
func ExceedsMinimumInt(name, in string, minimum int64, exclusive bool, value any) *Validation {
var message string
if in == "" {
m := minIncFailNoIn
@@ -432,8 +440,8 @@ func ExceedsMinimumInt(name, in string, minimum int64, exclusive bool, value int
}
}
// ExceedsMinimumUint error for when minimum validation fails
func ExceedsMinimumUint(name, in string, minimum uint64, exclusive bool, value interface{}) *Validation {
// ExceedsMinimumUint error for when minimum validation fails.
func ExceedsMinimumUint(name, in string, minimum uint64, exclusive bool, value any) *Validation {
var message string
if in == "" {
m := minIncFailNoIn
@@ -457,8 +465,8 @@ func ExceedsMinimumUint(name, in string, minimum uint64, exclusive bool, value i
}
}
// ExceedsMinimum error for when minimum validation fails
func ExceedsMinimum(name, in string, minimum float64, exclusive bool, value interface{}) *Validation {
// ExceedsMinimum error for when minimum validation fails.
func ExceedsMinimum(name, in string, minimum float64, exclusive bool, value any) *Validation {
var message string
if in == "" {
m := minIncFailNoIn
@@ -482,8 +490,8 @@ func ExceedsMinimum(name, in string, minimum float64, exclusive bool, value inte
}
}
// NotMultipleOf error for when multiple of validation fails
func NotMultipleOf(name, in string, multiple, value interface{}) *Validation {
// NotMultipleOf error for when multiple of validation fails.
func NotMultipleOf(name, in string, multiple, value any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(multipleOfFailNoIn, name, multiple)
@@ -499,8 +507,8 @@ func NotMultipleOf(name, in string, multiple, value interface{}) *Validation {
}
}
// EnumFail error for when an enum validation fails
func EnumFail(name, in string, value interface{}, values []interface{}) *Validation {
// EnumFail error for when an enum validation fails.
func EnumFail(name, in string, value any, values []any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(enumFailNoIn, name, values)
@@ -518,8 +526,8 @@ func EnumFail(name, in string, value interface{}, values []interface{}) *Validat
}
}
// Required error for when a value is missing
func Required(name, in string, value interface{}) *Validation {
// Required error for when a value is missing.
func Required(name, in string, value any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(requiredFailNoIn, name)
@@ -535,8 +543,8 @@ func Required(name, in string, value interface{}) *Validation {
}
}
// ReadOnly error for when a value is present in request
func ReadOnly(name, in string, value interface{}) *Validation {
// ReadOnly error for when a value is present in request.
func ReadOnly(name, in string, value any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(readOnlyFailNoIn, name)
@@ -552,8 +560,8 @@ func ReadOnly(name, in string, value interface{}) *Validation {
}
}
// TooLong error for when a string is too long
func TooLong(name, in string, maximum int64, value interface{}) *Validation {
// TooLong error for when a string is too long.
func TooLong(name, in string, maximum int64, value any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(tooLongMessageNoIn, name, maximum)
@@ -569,8 +577,8 @@ func TooLong(name, in string, maximum int64, value interface{}) *Validation {
}
}
// TooShort error for when a string is too short
func TooShort(name, in string, minimum int64, value interface{}) *Validation {
// TooShort error for when a string is too short.
func TooShort(name, in string, minimum int64, value any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(tooShortMessageNoIn, name, minimum)
@@ -589,7 +597,7 @@ func TooShort(name, in string, minimum int64, value interface{}) *Validation {
// FailedPattern error for when a string fails a regex pattern match
// the pattern that is returned is the ECMA syntax version of the pattern not the golang version.
func FailedPattern(name, in, pattern string, value interface{}) *Validation {
func FailedPattern(name, in, pattern string, value any) *Validation {
var msg string
if in == "" {
msg = fmt.Sprintf(patternFailNoIn, name, pattern)
@@ -607,8 +615,8 @@ func FailedPattern(name, in, pattern string, value interface{}) *Validation {
}
// MultipleOfMustBePositive error for when a
// multipleOf factor is negative
func MultipleOfMustBePositive(name, in string, factor interface{}) *Validation {
// multipleOf factor is negative.
func MultipleOfMustBePositive(name, in string, factor any) *Validation {
return &Validation{
code: MultipleOfMustBePositiveCode,
Name: name,

View File

@@ -318,8 +318,8 @@ github.com/go-openapi/analysis/internal/flatten/operations
github.com/go-openapi/analysis/internal/flatten/replace
github.com/go-openapi/analysis/internal/flatten/schutils
github.com/go-openapi/analysis/internal/flatten/sortref
# github.com/go-openapi/errors v0.22.1
## explicit; go 1.20
# github.com/go-openapi/errors v0.22.7
## explicit; go 1.24.0
github.com/go-openapi/errors
# github.com/go-openapi/jsonpointer v0.21.0
## explicit; go 1.20