much better errors

This commit is contained in:
vfs committed 2026-05-12 16:03:00 +02:00
1 parent 4e72beb433
commit 1913a0429f
26 files changed
+230 -444

No files matched your search

+100
View File
@@ -0,0 +1,100 @@
package data
import (
"fmt"
)
type ErrorCode int
const (
// 401 variants
ErrCodeInvalidCredentials ErrorCode = 4011
ErrCodeInvalidAuthToken ErrorCode = 4012
ErrCodeAuthRequired ErrorCode = 4013
// 403 variants
ErrCodeInactiveAccount ErrorCode = 4031
ErrCodeNotPermitted ErrorCode = 4032
// 409 variants
ErrCodeEditConflict ErrorCode = 4091
ErrCodeAlreadyVoted ErrorCode = 4092
ErrCodeAlreadyBlindSigned ErrorCode = 4093
ErrCodeVoteAlreadyCast ErrorCode = 4094
// 422 variants
ErrCodeValidationFailed ErrorCode = 4221
ErrCodeBlindedVoteRange ErrorCode = 4222
ErrCodeInvalidSignature ErrorCode = 4223
ErrCodeHasNotStarted ErrorCode = 4224
)
type Error struct {
HttpCode int `json:"http_code,omitempty"`
Code ErrorCode `json:"code,omitempty"`
Message string `json:"message"`
Details map[string]string `json:"details,omitempty"`
}
func (e *Error) Error() string {
return e.Message
}
func (e *Error) WithDetails(details map[string]string) error {
e.Details = details
return e
}
func (e *Error) DetailMessages() []string {
msgs := make([]string, 0, len(e.Details))
for key, msg := range e.Details {
msgs = append(msgs, fmt.Sprintf("%s: %s", key, msg))
}
return msgs
}
func New(httpCode int, code ErrorCode, text string) error {
return &Error{HttpCode: httpCode, Code: code, Message: text}
}
var (
// 400 Bad Request
ErrFailedPEM = New(400, 0, "failed to decode PEM block")
ErrBadlyFormedJSON = New(400, 0, "body contains badly-formed JSON")
ErrBodyEmpty = New(400, 0, "body must not be empty")
ErrSingleValue = New(400, 0, "body must only contain a single JSON value")
ErrInvalidID = New(400, 0, "invalid id parameter")
ErrBadRequest = New(400, 0, "the server cannot process the request due to a client error")
// 401 Unauthorized
ErrInvalidCredentials = New(401, 4011, "invalid credentials")
ErrInvalidAuthToken = New(401, 4012, "invalid or missing authentication token")
ErrNoToken = New(401, 4012, "token must be provided")
ErrAuthRequired = New(401, 4013, "you must be authenticated to access this resource")
ErrHasNotStarted = New(401, 4224, "the vote has not yet started")
// 403 Forbidden
ErrInactiveAccount = New(403, 4031, "your user account must be activated to access this resource")
ErrNotPermitted = New(403, 4032, "your user account doesn't have the necessary permissions to access this resource")
// 404 Not Found
ErrRecordNotFound = New(404, 0, "record not found")
ErrNoPath = New(404, 0, "path is required")
// 409 Conflict
ErrEditConflict = New(409, 4091, "edit conflict")
ErrDuplicateVote = New(409, 4092, "this signature has already been used to cast a vote")
ErrDuplicateBlindSign = New(409, 4093, "user has already requested a blind signature for this issue")
ErrDuplicateSignature = New(409, 4094, "this signature has already been used to cast a vote")
ErrDuplicateEmail = New(409, 0, "duplicate email")
ErrDuplicateUser = New(409, 0, "duplicate username")
// 422 Unprocessable Entity
ErrValidationFailed = New(422, 4221, "validation failed")
ErrInvalidBlindedVote = New(422, 4222, "blinded_vote is out of valid range [1, n-1]")
ErrInvalidSignature = New(422, 4223, "signature verification failed")
// 429 Too Many Requests
ErrRateLimitExceeded = New(429, 0, "rate limit exceeded")
)
+1 -2
View File
@@ -3,14 +3,13 @@ package data
import(
"crypto/rsa"
"encoding/pem"
"errors"
"crypto/x509"
)
func parsePrivateKey(pemBytes []byte) (*rsa.PrivateKey, error) {
block, _ := pem.Decode(pemBytes)
if block == nil {
return nil, errors.New("failed to decode PEM block")
return nil, ErrFailedPEM
}
return x509.ParsePKCS1PrivateKey(block.Bytes)
}
-6
View File
@@ -2,12 +2,6 @@ package data
import (
"database/sql"
"errors"
)
var (
ErrRecordNotFound = errors.New("record not found")
ErrEditConflict = errors.New("edit conflict")
)
type Models struct {
-6
View File
@@ -12,12 +12,6 @@ import (
"party.at/party/internal/validator"
)
var (
ErrDuplicateEmail = errors.New("duplicate email")
ErrDuplicateUser = errors.New("duplicate username")
ErrInvalidCredentials = errors.New("invalid credentials")
)
var AnonymousUser = &User{}
type User struct {
-9
View File
@@ -1,7 +1,6 @@
package data
import (
"errors"
"time"
"database/sql"
"math/big"
@@ -12,14 +11,6 @@ import (
"github.com/lib/pq"
)
var (
ErrDuplicateBlindSign = errors.New("user has already requested a blind signature for this issue")
ErrInvalidBlindedVote = errors.New("blinded_vote is out of valid range [1, n-1]")
ErrInvalidSignature = errors.New("signature verification failed")
ErrDuplicateVote = errors.New("this signature has already been used to cast a vote")
)
type Vote struct {
ID int64 `json:"id"`
OptionID int64 `json:"option_id"`