Something went wrong. Try again.
An ATProto Powered Reputation Network
Something went wrong. Try again.
3.1 kB · 76 lines
Go
at master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677package ui
import ( "context" "errors" "net" "net/http" "strings"
"github.com/bluesky-social/indigo/atproto/atclient" "github.com/bluesky-social/indigo/atproto/identity" "github.com/bluesky-social/indigo/atproto/syntax")
type requestError struct { status int code string message string cause error}
func (e *requestError) Error() string { return e.message }func (e *requestError) Unwrap() error { return e.cause }
func invalid(message string, err error) error { return &requestError{http.StatusBadRequest, "invalid_input", message, err}}
func accountInput(value string) (string, error) { value = cleanAccount(value) if _, err := syntax.ParseAtIdentifier(value); err != nil { return "", invalid("Enter a full account handle or DID, not a display name or server URL.", err) } return value, nil}
func cleanAccount(value string) string { value = strings.TrimSpace(value) if strings.HasPrefix(value, "did:") { return value } return strings.ToLower(strings.TrimPrefix(value, "@"))}
func describeError(err error, path string) *requestError { var network net.Error if errors.Is(err, context.DeadlineExceeded) || errors.As(err, &network) && network.Timeout() { return &requestError{http.StatusGatewayTimeout, "timeout", "The service took too long to respond. Check your vouches before you repeat a publish request.", err} } var api *atclient.APIError if errors.As(err, &api) && (api.StatusCode == http.StatusUnauthorized || api.StatusCode == http.StatusForbidden) { return &requestError{http.StatusUnauthorized, "authorization_failed", "Your account provider did not authorize this action. Log out and log in again to renew permissions.", err} } if api != nil && api.StatusCode == http.StatusBadRequest { return &requestError{http.StatusBadRequest, "invalid_query", "The query is invalid or contains options that the active trust algorithm does not support.", err} } if errors.Is(err, identity.ErrHandleNotFound) || errors.Is(err, identity.ErrDIDNotFound) { return &requestError{http.StatusUnprocessableEntity, "account_not_found", "We could not find that account. Check its full handle or DID. Do not use the server address.", err} } var problem *requestError if errors.As(err, &problem) { return problem } code, message := "service_unavailable", "Provenance cannot complete this request. Try again later." switch path { case "/api/accounts": code, message = "search_unavailable", "Account search is unavailable. Enter a full handle or DID instead." case "/api/vouch": code, message = "pds_write_failed", "Your account provider did not confirm the change. Check your vouches before you try again." case "/api/reputation", "/api/aggregate": code, message = "reputation_unavailable", "We cannot check reputation right now. Check the account handle, then try again later." case "/oauth/login", "/oauth/callback": code, message = "login_failed", "We could not complete login. Check your account handle and try again." } return &requestError{http.StatusBadGateway, code, message, err}}