djangoauthenticationdjango-socialauth

How can I handle Exceptions raised by dango-social-auth?


In django-social-auth, there are a few instances where a back-end will raise a ValueError (such as when a user cancels a login request or if a user tries to associate with an account that's already been associated with another User). If a User runs into one of these scenarios, they'll be presented with a 500 error on your site.

So, what's the best way to catch these? I'd prefer to be able to display a useful message (via the messages framework) when this happens, but I'm at a loss as to the best way to do this.

I'm thinking about writing my own view (in a separate app) that just wraps social_auth's associate_complete view, but this seems clunky... Any ideas?

I could fork django-social-auth and customize this behavior, but I'd prefer not to maintain a separate fork - especially since I can't assume everone would want to handle these Exceptions in the same manner.


Solution

  • I've ecountered the same problem and it seems, that creating wrapper view is the best way to handle this situation, at this point, atleast. Here is how I had mine done:

    def social_auth_login(request, backend):
        """
            This view is a wrapper to social_auths auth
            It is required, because social_auth just throws ValueError and gets user to 500 error
            after every unexpected action. This view handles exceptions in human friendly way.
            See https://convore.com/django-social-auth/best-way-to-handle-exceptions/
        """
        from social_auth.views import auth
    
        try:
            # if everything is ok, then original view gets returned, no problem
            return auth(request, backend)
        except ValueError, error:
            # in case of errors, let's show a special page that will explain what happened
            return render_to_response('users/login_error.html',
                                      locals(),
                                      context_instance=RequestContext(request))
    

    You will have to setup url for it:

    urlpatterns = patterns('',
        # ...
        url(r'^social_auth_login/([a-z]+)$',  social_auth_login, name='users-social-auth-login'), 
    )
    

    And then use it as before in template:

    <a href="{% url 'users-social-auth-login' "google" %}">Log in with Google</a>
    

    Hope this helps, even aftern two months after question was asked :)