1
0
Fork 0
golang-github-meilisearch-m.../error.go
Daniel Baumann 5d4914ed7f
Adding upstream version 0.31.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-18 21:42:39 +02:00

189 lines
6.5 KiB
Go

package meilisearch
import (
"encoding/json"
"errors"
"fmt"
"strings"
)
// ErrCode are all possible errors found during requests
type ErrCode int
const (
// ErrCodeUnknown default error code, undefined
ErrCodeUnknown ErrCode = 0
// ErrCodeMarshalRequest impossible to serialize request body
ErrCodeMarshalRequest ErrCode = iota + 1
// ErrCodeResponseUnmarshalBody impossible deserialize the response body
ErrCodeResponseUnmarshalBody
// MeilisearchApiError send by the meilisearch api
MeilisearchApiError
// MeilisearchApiErrorWithoutMessage MeilisearchApiError send by the meilisearch api
MeilisearchApiErrorWithoutMessage
// MeilisearchTimeoutError
MeilisearchTimeoutError
// MeilisearchCommunicationError impossible execute a request
MeilisearchCommunicationError
// MeilisearchMaxRetriesExceeded used max retries and exceeded
MeilisearchMaxRetriesExceeded
)
const (
rawStringCtx = `(path "${method} ${endpoint}" with method "${function}")`
rawStringMarshalRequest = `unable to marshal body from request: '${request}'`
rawStringResponseUnmarshalBody = `unable to unmarshal body from response: '${response}' status code: ${statusCode}`
rawStringMeilisearchApiError = `unaccepted status code found: ${statusCode} expected: ${statusCodeExpected}, MeilisearchApiError Message: ${message}, Code: ${code}, Type: ${type}, Link: ${link}`
rawStringMeilisearchApiErrorWithoutMessage = `unaccepted status code found: ${statusCode} expected: ${statusCodeExpected}, MeilisearchApiError Message: ${message}`
rawStringMeilisearchTimeoutError = `MeilisearchTimeoutError`
rawStringMeilisearchCommunicationError = `MeilisearchCommunicationError unable to execute request`
rawStringMeilisearchMaxRetriesExceeded = "failed to request and max retries exceeded"
)
func (e ErrCode) rawMessage() string {
switch e {
case ErrCodeMarshalRequest:
return rawStringMarshalRequest + " " + rawStringCtx
case ErrCodeResponseUnmarshalBody:
return rawStringResponseUnmarshalBody + " " + rawStringCtx
case MeilisearchApiError:
return rawStringMeilisearchApiError + " " + rawStringCtx
case MeilisearchApiErrorWithoutMessage:
return rawStringMeilisearchApiErrorWithoutMessage + " " + rawStringCtx
case MeilisearchTimeoutError:
return rawStringMeilisearchTimeoutError + " " + rawStringCtx
case MeilisearchCommunicationError:
return rawStringMeilisearchCommunicationError + " " + rawStringCtx
case MeilisearchMaxRetriesExceeded:
return rawStringMeilisearchMaxRetriesExceeded + " " + rawStringCtx
default:
return rawStringCtx
}
}
type meilisearchApiError struct {
Message string `json:"message"`
Code string `json:"code"`
Type string `json:"type"`
Link string `json:"link"`
}
// Error is the internal error structure that all exposed method use.
// So ALL errors returned by this library can be cast to this struct (as a pointer)
type Error struct {
// Endpoint is the path of the request (host is not in)
Endpoint string
// Method is the HTTP verb of the request
Method string
// Function name used
Function string
// RequestToString is the raw request into string ('empty request' if not present)
RequestToString string
// RequestToString is the raw request into string ('empty response' if not present)
ResponseToString string
// Error info from meilisearch api
// Message is the raw request into string ('empty meilisearch message' if not present)
MeilisearchApiError meilisearchApiError
// StatusCode of the request
StatusCode int
// StatusCode expected by the endpoint to be considered as a success
StatusCodeExpected []int
rawMessage string
// OriginError is the origin error that produce the current Error. It can be nil in case of a bad status code.
OriginError error
// ErrCode is the internal error code that represent the different step when executing a request that can produce
// an error.
ErrCode ErrCode
encoder
}
// Error return a well human formatted message.
func (e *Error) Error() string {
message := namedSprintf(e.rawMessage, map[string]interface{}{
"endpoint": e.Endpoint,
"method": e.Method,
"function": e.Function,
"request": e.RequestToString,
"response": e.ResponseToString,
"statusCodeExpected": e.StatusCodeExpected,
"statusCode": e.StatusCode,
"message": e.MeilisearchApiError.Message,
"code": e.MeilisearchApiError.Code,
"type": e.MeilisearchApiError.Type,
"link": e.MeilisearchApiError.Link,
})
if e.OriginError != nil {
return fmt.Sprintf("%s: %s", message, e.OriginError.Error())
}
return message
}
// WithErrCode add an error code to an error
func (e *Error) WithErrCode(err ErrCode, errs ...error) *Error {
if errs != nil {
e.OriginError = errs[0]
}
e.rawMessage = err.rawMessage()
e.ErrCode = err
return e
}
// ErrorBody add a body to an error
func (e *Error) ErrorBody(body []byte) {
msg := meilisearchApiError{}
if e.encoder != nil {
err := e.encoder.Decode(body, &msg)
if err == nil {
e.MeilisearchApiError.Message = msg.Message
e.MeilisearchApiError.Code = msg.Code
e.MeilisearchApiError.Type = msg.Type
e.MeilisearchApiError.Link = msg.Link
}
return
}
e.ResponseToString = string(body)
err := json.Unmarshal(body, &msg)
if err == nil {
e.MeilisearchApiError.Message = msg.Message
e.MeilisearchApiError.Code = msg.Code
e.MeilisearchApiError.Type = msg.Type
e.MeilisearchApiError.Link = msg.Link
}
}
// VersionErrorHintMessage a hint to the error message if it may come from a version incompatibility with meilisearch
func VersionErrorHintMessage(err error, req *internalRequest) error {
return fmt.Errorf("%w. Hint: It might not be working because you're not up to date with the "+
"Meilisearch version that %s call requires", err, req.functionName)
}
func namedSprintf(format string, params map[string]interface{}) string {
for key, val := range params {
format = strings.ReplaceAll(format, "${"+key+"}", fmt.Sprintf("%v", val))
}
return format
}
// General errors
var (
ErrInvalidRequestMethod = errors.New("request body is not expected for GET and HEAD requests")
ErrRequestBodyWithoutContentType = errors.New("request body without Content-Type is not allowed")
ErrNoSearchRequest = errors.New("no search request provided")
ErrNoFacetSearchRequest = errors.New("no search facet request provided")
ErrConnectingFailed = errors.New("meilisearch is not connected")
)