Files

115 lines
2.7 KiB
Go
Raw Permalink Normal View History

2021-10-22 22:40:03 +02:00
package http
2018-08-05 18:25:59 +02:00
// Improve error handling
// Create api.ErrorResponses based on errors returned from server.
// Strip out potentially sensitive information, eg. connection errors
// to internal IP addresses.
import (
2019-01-11 20:06:03 +01:00
"net/http"
2018-08-05 18:25:59 +02:00
"net/url"
"strings"
2021-03-22 16:50:08 +01:00
"github.com/alice-lg/alice-lg/pkg/api"
2018-08-05 18:25:59 +02:00
)
2021-10-26 23:11:42 +02:00
// ErrResourceNotFoundError is a 404 error
type ErrResourceNotFoundError struct{}
2019-01-11 20:06:03 +01:00
2021-03-22 16:50:08 +01:00
// Error implements the error interface and returns
// the error message
2021-10-26 23:11:42 +02:00
func (err *ErrResourceNotFoundError) Error() string {
2019-01-11 20:06:03 +01:00
return "resource not found"
}
2023-05-12 14:37:28 +02:00
// ErrTimeout will be sent if the request took too long
type ErrTimeout string
// Implement Error interface
func (err ErrTimeout) Error() string {
return string(err)
}
2021-03-22 16:50:08 +01:00
// Variables
var (
2021-10-26 23:11:42 +02:00
ErrSourceNotFound = &ErrResourceNotFoundError{}
2021-03-22 16:50:08 +01:00
)
2019-01-11 20:06:03 +01:00
2021-10-26 23:11:42 +02:00
// Error tags
2018-08-05 18:25:59 +02:00
const (
2021-10-26 23:11:42 +02:00
TagGenericError = "GENERIC_ERROR"
TagConnectionRefused = "CONNECTION_REFUSED"
TagConnectionTimeout = "CONNECTION_TIMEOUT"
TagResourceNotFound = "NOT_FOUND"
2022-06-20 18:00:41 +02:00
TagValidationError = "VALIDATION_ERROR"
2018-08-05 18:25:59 +02:00
)
2021-10-26 23:11:42 +02:00
// Error codes
2018-08-05 18:25:59 +02:00
const (
2021-10-26 23:11:42 +02:00
CodeGeneric = 42
CodeConnectionRefused = 100
CodeConnectionTimeout = 101
2022-06-20 18:00:41 +02:00
CodeValidationError = 400
2021-10-26 23:11:42 +02:00
CodeResourceNotFound = 404
2018-08-05 18:25:59 +02:00
)
2021-10-26 23:11:42 +02:00
// Error status codes
2019-01-11 20:06:03 +01:00
const (
2021-10-26 23:11:42 +02:00
StatusError = http.StatusInternalServerError
StatusResourceNotFound = http.StatusNotFound
2022-06-20 18:00:41 +02:00
StatusValidationError = http.StatusBadRequest
2023-05-12 14:37:28 +02:00
TimeoutError = http.StatusGatewayTimeout
2019-01-11 20:06:03 +01:00
)
2021-03-22 16:50:08 +01:00
// Handle an error and create a error API response
2021-10-26 23:11:42 +02:00
func apiErrorResponse(
routeserverID string,
err error,
) (api.ErrorResponse, int) {
code := CodeGeneric
2018-08-05 18:25:59 +02:00
message := err.Error()
2021-10-26 23:11:42 +02:00
tag := TagGenericError
status := StatusError
2018-08-05 18:25:59 +02:00
2024-01-26 14:19:18 +01:00
// TODO: This needs refactoring.
if err == api.ErrTooManyRoutes {
2022-06-20 18:00:41 +02:00
tag = TagValidationError
code = CodeValidationError
status = StatusValidationError
2024-01-26 14:19:18 +01:00
} else {
switch e := err.(type) {
case ErrTimeout:
tag = TagConnectionTimeout
code = CodeConnectionTimeout
status = TimeoutError
case *ErrResourceNotFoundError:
tag = TagResourceNotFound
code = CodeResourceNotFound
status = StatusResourceNotFound
case *url.Error:
if strings.Contains(message, "connection refused") {
tag = TagConnectionRefused
code = CodeConnectionRefused
message = "Connection refused while dialing the API"
} else if e.Timeout() {
tag = TagConnectionTimeout
code = CodeConnectionTimeout
message = "Connection timed out when connecting to the backend API"
}
case *ErrValidationFailed:
tag = TagValidationError
code = CodeValidationError
status = StatusValidationError
message = e.Reason
}
2022-06-20 18:00:41 +02:00
}
2018-08-05 18:25:59 +02:00
return api.ErrorResponse{
Code: code,
Tag: tag,
Message: message,
2021-10-26 23:11:42 +02:00
RouteserverID: routeserverID,
2019-01-11 20:06:03 +01:00
}, status
2018-08-05 18:25:59 +02:00
}