Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nginx 499 and IntegrityError #447

Open
JulienPalard opened this issue May 14, 2024 · 1 comment
Open

Nginx 499 and IntegrityError #447

JulienPalard opened this issue May 14, 2024 · 1 comment

Comments

@JulienPalard
Copy link

I'm mostly opening the issue to document the fact. This could not be considered as a django-registration bug.

I'm getting a few IntegrityError on my Django Registration setup, like :

IntegrityError at /accounts/register/

duplicate key value violates unique constraint "auth_user_username_key"
DETAIL:  Key (username)=(test) already exists.

I found this is correlated with errors 499 in nginx, meaning "client closed the connection", so I dug the issue and here's what I found:

  • A user fills the registration form and double clicks on the submit button (Firefox prevents this, but not Chromium, I did not tested other browsers).
  • At the 1st click, a first POST request is sent.
  • The 2nd click happen, the browser "cancels" the 1st POST by closing the connection and emit a 2nd POST request.
  • The 1st POST successfully passes form validation, INSERTs the user, ...
  • The 2nd POST successfully passes form validation (username uniqueness).
  • The 1st POST commits to the database.
  • Nginx notices the first POST connection has closed and logs a 499.
  • The 2nd POST tries to INSERT the user and gets an IntegrityError, gives back a 500 error.

In the nginx logs it looks like this:

www.hackinscience.org 2001:redacted:8aba - - [14/May/2024:09:41:12 +0200] "POST /accounts/register/ HTTP/2.0" 499 0.192 0 "https://www.hackinscience.org/accounts/register/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
www.hackinscience.org 2001:redacted:8aba - - [14/May/2024:09:41:13 +0200] "POST /accounts/register/ HTTP/2.0" 500 1.426 145 "https://www.hackinscience.org/accounts/register/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"

Now, what's the correct way to fix this? Should I add JS client-side to avoid double-form submission?

It's tempting to say that IntegrityError could be catched and re-raised as ValidationError in django-registration but it does not fix the issue: the user would be presented with a false "Username already exists" error, while he just had successfully created an account...

It's also tempting to say it's a Django design issue: separating form validation and form saving looks like calling for race conditions, but same as previous: "fixing" this design issue would just lead to present a "Username already exists" instead of a 500, I prefer the error :D

@JulienPalard
Copy link
Author

I'm not a front-end dev, but I tried hard, I came by this:

https://framagit.org/hackinscience/hkis-website/-/commit/62f479c0eb7c7db8ee0c49eb0a98560ea710bb99

window.addEventListener("DOMContentLoaded", function (event) {
    const form = document.getElementById('registration_form');
    const button = document.getElementById('registration_button');
    form.addEventListener('submit', function(event) {
        if (button.disabled)
	    return false;
        button.disabled = true;
    });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant