Skip to main content

Error Handling

Complete guide to handling OAuth errors gracefully.

Common Errors

SVATokenError

Raised when token operations fail:

from sva_oauth_client.client import SVATokenError
from sva_oauth_client.utils import get_sva_claims

try:
claims = get_sva_claims(request)
except SVATokenError:
# Token expired or invalid
# Handle error
pass

Common causes:

  • Token expired
  • Invalid token signature
  • Token not found in session

SVAAuthorizationError

Raised when authorization fails:

from sva_oauth_client.client import SVAAuthorizationError, SVAOAuthClient

try:
tokens = client.exchange_code_for_tokens(code, code_verifier)
except SVAAuthorizationError:
# Authorization failed
pass

Common causes:

  • Invalid authorization code
  • Code already used
  • Code expired
  • Invalid redirect URI

Error Handling Patterns

Basic Error Handling

from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError
from django.shortcuts import redirect
from django.contrib import messages

@sva_oauth_required
def my_view(request):
try:
claims = get_sva_claims(request)
# Process claims...
except SVATokenError:
messages.error(request, 'Your session has expired. Please sign in again.')
return redirect('sva_oauth_client:login')

Comprehensive Error Handling

from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError, SVAAuthorizationError, SVAOAuthError
import logging

logger = logging.getLogger(__name__)

@sva_oauth_required
def my_view(request):
try:
claims = get_sva_claims(request)
# Process claims...
except SVATokenError as e:
logger.warning(f"Token error: {e}")
messages.error(request, 'Authentication failed. Please sign in again.')
return redirect('sva_oauth_client:login')
except SVAOAuthError as e:
logger.error(f"OAuth error: {e}")
messages.error(request, 'An error occurred. Please try again.')
return redirect('/')
except Exception as e:
logger.exception(f"Unexpected error: {e}")
messages.error(request, 'An unexpected error occurred.')
return redirect('/')

Decorator Error Handling

Automatic Error Handling

The @sva_oauth_required decorator handles errors automatically:

  • Token errors → Redirects to login
  • Missing authentication → Redirects to login
  • Displays appropriate messages

Custom Error Messages

from sva_oauth_client.decorators import sva_blocks_required
from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError

@sva_blocks_required('email', 'name')
def my_view(request):
try:
claims = get_sva_claims(request)
# Process claims...
except SVATokenError:
# Decorator handles logout, but you can add custom logic
messages.warning(request, 'Your session expired. Please sign in again.')
return redirect('sva_oauth_client:login')

Token Refresh Errors

Handling Refresh Failures

from sva_oauth_client.client import get_client_from_settings, SVATokenError

def refresh_token_safely(request):
"""Safely refresh token with error handling"""
refresh_token = request.session.get('sva_oauth_refresh_token')

if not refresh_token:
return False

try:
client = get_client_from_settings()
new_tokens = client.refresh_access_token(refresh_token)

# Update session
request.session['sva_oauth_access_token'] = new_tokens['access_token']
# ... update other tokens

return True
except SVATokenError as e:
# Refresh failed - token expired or revoked
logger.warning(f"Token refresh failed: {e}")
clear_oauth_session(request.session)
return False

OAuth Flow Errors

Authorization Errors

from sva_oauth_client.client import SVAOAuthClient, SVAAuthorizationError

def handle_oauth_callback(request):
code = request.GET.get('code')
error = request.GET.get('error')

if error:
# User denied authorization
messages.error(request, 'Authorization was denied.')
return redirect('/')

if not code:
messages.error(request, 'No authorization code received.')
return redirect('/')

try:
client = SVAOAuthClient(...)
tokens = client.exchange_code_for_tokens(code, code_verifier)
# Process tokens...
except SVAAuthorizationError as e:
messages.error(request, 'Authorization failed. Please try again.')
return redirect('sva_oauth_client:login')

Validation Errors

Missing Blocks

from sva_oauth_client.decorators import sva_oauth_required
from sva_oauth_client.utils import get_sva_claims

@sva_oauth_required
def my_view(request):
claims = get_sva_claims(request)

required_blocks = ['email', 'name', 'phone']
missing = [block for block in required_blocks if block not in claims]

if missing:
messages.warning(
request,
f'Missing required data: {", ".join(missing)}. Please sign in again and approve these permissions.'
)
return redirect('sva_oauth_client:login')

# All required blocks are present
return render(request, 'template.html', {'claims': claims})

Logging Errors

Error Logging

import logging

logger = logging.getLogger(__name__)

@sva_oauth_required
def my_view(request):
try:
claims = get_sva_claims(request)
except SVATokenError as e:
logger.warning(f"Token error for user: {e}", exc_info=True)
# Handle error...
except Exception as e:
logger.error(f"Unexpected error: {e}", exc_info=True)
# Handle error...

User-Friendly Messages

Error Messages

from django.contrib import messages

# Token expired
messages.error(request, 'Your session has expired. Please sign in again.')

# Authorization denied
messages.warning(request, 'Authorization was denied. Please try again.')

# Missing blocks
messages.info(request, 'Please approve the requested permissions to continue.')

# General error
messages.error(request, 'An error occurred. Please try again.')

Error Recovery

Retry Logic

from sva_oauth_client.utils import get_sva_claims
from sva_oauth_client.client import SVATokenError

def get_claims_with_retry(request, max_retries=2):
"""Get claims with retry logic"""
for attempt in range(max_retries):
try:
return get_sva_claims(request)
except SVATokenError:
if attempt < max_retries - 1:
# Try to refresh token
if refresh_token_safely(request):
continue
# All retries failed
raise

Best Practices

  1. Always handle errors - Don't let errors crash your app
  2. Log errors - Help with debugging
  3. User-friendly messages - Don't expose technical details
  4. Graceful degradation - Handle missing data gracefully
  5. Retry logic - For transient errors

Next Steps