Remove redundant API error type, use arcgis

That's what the library is supposed to be for.
Errors still aren't working quite right.
This commit is contained in:
Eli Ribble 2025-11-14 23:08:26 +00:00
parent e48abb09c0
commit 0614a768c3
No known key found for this signature in database
3 changed files with 22 additions and 28 deletions

@ -1 +1 @@
Subproject commit 23d266764b71d0686e529392f785ebc4439e034e Subproject commit 6344702fe14c9f64a1ea856e9629248bbaabe894

View file

@ -30,6 +30,11 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
// When the API responds that the token is now invalidated
type InvalidatedTokenError struct{}
func (e InvalidatedTokenError) Error() string { return "The token has been invalidated by the server" }
// When there is no oauth for an organization // When there is no oauth for an organization
type NoOAuthForOrg struct{} type NoOAuthForOrg struct{}
@ -38,18 +43,6 @@ func (e NoOAuthForOrg) Error() string { return "No oauth available for organizat
var NewOAuthTokenChannel chan struct{} var NewOAuthTokenChannel chan struct{}
var CodeVerifier string = "random_secure_string_min_43_chars_long_should_be_stored_in_session" var CodeVerifier string = "random_secure_string_min_43_chars_long_should_be_stored_in_session"
type ErrorResponse struct {
Error ErrorResponseContent `json:"error"`
}
type ErrorResponseContent struct {
Code int `json:"code"`
Error string `json:"error"`
ErrorDescription string `json:"error_description"`
Message string `json:"message"`
Details []string `json:"details"`
}
type OAuthTokenResponse struct { type OAuthTokenResponse struct {
AccessToken string `json:"access_token"` AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"` ExpiresIn int `json:"expires_in"`
@ -278,6 +271,11 @@ func refreshFieldseekerData(ctx context.Context, newOauthCh <-chan struct{}) {
defer wg.Done() defer wg.Done()
err := maintainOAuth(workerCtx, oauth) err := maintainOAuth(workerCtx, oauth)
if err != nil { if err != nil {
LogErrorTypeInfo(err)
if errors.Is(err, &InvalidatedTokenError{}) {
log.Info().Int("oauth_token.id", int(oauth.ID)).Msg("The server has marked the token invalid")
return
}
log.Error().Err(err).Msg("Crashed oauth maintenance goroutine") log.Error().Err(err).Msg("Crashed oauth maintenance goroutine")
} }
}() }()
@ -606,8 +604,11 @@ func handleTokenRequest(ctx context.Context, req *http.Request) (*OAuthTokenResp
return nil, fmt.Errorf("Got status code %d and failed to read response body: %w", resp.StatusCode, err) return nil, fmt.Errorf("Got status code %d and failed to read response body: %w", resp.StatusCode, err)
} }
bodyString := string(bodyBytes) bodyString := string(bodyBytes)
var errorResp map[string]interface{} var errorResp arcgis.ErrorResponse
if err := json.Unmarshal(bodyBytes, &errorResp); err == nil { if err := json.Unmarshal(bodyBytes, &errorResp); err == nil {
if errorResp.Error.Code == 498 && errorResp.Error.Description == "invalidated refresh_token" {
return nil, InvalidatedTokenError{}
}
return nil, fmt.Errorf("API response JSON error: %d: %w", resp.StatusCode, errorResp) return nil, fmt.Errorf("API response JSON error: %d: %w", resp.StatusCode, errorResp)
} }
return nil, fmt.Errorf("API returned error status %d: %s", resp.StatusCode, bodyString) return nil, fmt.Errorf("API returned error status %d: %s", resp.StatusCode, bodyString)
@ -621,18 +622,13 @@ func handleTokenRequest(ctx context.Context, req *http.Request) (*OAuthTokenResp
// Just because we got a 200-level status code doesn't mean it worked. Experience has taught us that // Just because we got a 200-level status code doesn't mean it worked. Experience has taught us that
// we can get errors without anything indicated in the headers or the status code // we can get errors without anything indicated in the headers or the status code
if tokenResponse == (OAuthTokenResponse{}) { if tokenResponse == (OAuthTokenResponse{}) {
var errorResponse ErrorResponse var errorResponse arcgis.ErrorResponse
err = json.Unmarshal(bodyBytes, &errorResponse) err = json.Unmarshal(bodyBytes, &errorResponse)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to unmarshal error JSON: %w", err) return nil, fmt.Errorf("Failed to unmarshal error JSON: %w", err)
} }
if errorResponse.Error.Code > 0 { if errorResponse.Error.Code > 0 {
return nil, errors.New(fmt.Sprintf("API error %d: %s: %s (%s)", return nil, errorResponse.AsError()
errorResponse.Error.Code,
errorResponse.Error.Error,
errorResponse.Error.ErrorDescription,
errorResponse.Error.Message,
))
} }
} }
log.Info().Str("refresh token", tokenResponse.RefreshToken).Str("access token", tokenResponse.AccessToken).Int("access expires", tokenResponse.ExpiresIn).Int("refresh expires", tokenResponse.RefreshTokenExpiresIn).Msg("Oauth token acquired") log.Info().Str("refresh token", tokenResponse.RefreshToken).Str("access token", tokenResponse.AccessToken).Int("access expires", tokenResponse.ExpiresIn).Int("refresh expires", tokenResponse.RefreshTokenExpiresIn).Msg("Oauth token acquired")

View file

@ -2,27 +2,25 @@ package main
import ( import (
"errors" "errors"
"log/slog"
"reflect" "reflect"
"github.com/rs/zerolog/log"
) )
func LogErrorTypeInfo(err error) { func LogErrorTypeInfo(err error) {
if err == nil { if err == nil {
slog.Info("Error is nil") log.Error().Msg("Error is nil")
return return
} }
// Log current error type // Log current error type
errType := reflect.TypeOf(err) errType := reflect.TypeOf(err)
slog.Info("Error type info", log.Warn().Err(err).Str("type", errType.String()).Str("pkgPath", errType.PkgPath()).Msg("Error type info")
"type", errType.String(),
"pkgPath", errType.PkgPath(),
"error", err.Error())
// Recursively log wrapped errors // Recursively log wrapped errors
wrappedErr := errors.Unwrap(err) wrappedErr := errors.Unwrap(err)
if wrappedErr != nil { if wrappedErr != nil {
slog.Info("Contains wrapped error") log.Info().Msg("Contains wrapped error")
LogErrorTypeInfo(wrappedErr) LogErrorTypeInfo(wrappedErr)
} }
} }