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
- Always handle errors - Don't let errors crash your app
- Log errors - Help with debugging
- User-friendly messages - Don't expose technical details
- Graceful degradation - Handle missing data gracefully
- Retry logic - For transient errors
Next Steps
- Learn about Token Management
- Explore Security Best Practices
- Check Troubleshooting