'ActionController::RoutingError (No route matches [GET] every page)

Sometimes I got RoutingError for every page on production (or staging) server. This error doesn't happen often, it happens once every 2 to 3 months

Error memo: Start puma => request for all page are ok, after the times (2-3 days) suddenly all request get ActionController::RoutingError (No route matches [GET] "/page" => Restart puma, request for all page are ok.

Does anyone know what's wrong with it?

Puma config:

#!/usr/bin/env puma

directory '/var/www/project/current'
rackup "/var/www/project/current/config.ru"
environment 'production'
tag ''
pidfile "/var/www/project/shared/tmp/pids/puma.pid"
state_path "/var/www/project/shared/tmp/pids/puma.state"
stdout_redirect '/var/www/project/shared/log/puma_access.log', '/var/www/project/shared/log/puma_error.log', true
threads 0,16
bind 'unix:///var/www/project/shared/tmp/sockets/puma.sock'
workers 0
prune_bundler
on_restart do
  puts 'Refreshing Gemfile'
  ENV["BUNDLE_GEMFILE"] = ""
end

ServerInfo

  • OS: Linux
  • Rails: 5.1.6
  • Puma Version: 3.12.0


Solution 1:[1]

The problem comes from your register view, you have imported the "from django.contrib.auth import get_user_model" and "from django.contrib.auth.models import User" which you need to take out from your imports models.

# django imports 
from django.shortcuts import render , HttpResponse, redirect
from django.contrib.auth import authenticate, login
#from django.contrib.auth.models import User this where where your problem comes from
# from django.contrib.auth import get_user_model 
# now you would need to import the Account model since you are not using djangos build in User model 
from account.models import Account 


# app imports 
from .forms import RegistrationForm


# Create your views here.
# user = get_user_model() You would have to delete this or just comment it out .

# register page here

def register_view(request, *args, **kwargs):
    context = {}
    user = request.user
    if user.is_authenticated:
        return redirect("home")
    elif (request.method == 'POST'):
        print("hello")
        form = RegistrationForm(request.POST)
        print(form)
        if form.is_valid():
            form.save()
            email = form.cleaned_data.get('email').lower()
            raw_password = form.cleaned_data.get('password1')
            account = authenticate(email=email,password=raw_password)
            login(request,account)
            destination = kwargs.get("next")
            if destination:
                return redirect(destination)
            else:
                pass
        else:
            context['registration_form'] = form

    else:
        form = RegistrationForm()
        context['registration_form'] = form
    return render(request, 'account/register.html',context)

I also observed that you have an attribute in your models manager filed which is not in your account field, which in think would raise exception of attribute error when your try to create an account so i so guess you delete the profile attribute from your manager and also from your form. Here is my solution .

class MyAccountManager(BaseUserManager):
    def create_user(self, email, username, password=None):
        if not email:
            raise ValueError('Users must have an email address')
        if not username:
            raise ValueError('Users must have a username')

Your form.py: Everything should now work perfectly hopefully!

class RegistrationForm(UserCreationForm):
    email       = forms.EmailField(max_length=255, required=True, help_text="Enter a valid email ")
    class meta:
        model = Account
        fields = ('email','username','password1','password2')
    

    def clean_email(self):
        email = self.cleaned_data["email"].lower()
        try:
            account = Account.objects.get(email=email)
        except:
            return email
        raise forms.ValidationError(f"email{email} is already in use.")
    
    def clean_username(self):
        username = self.cleaned_data["username"]
        try:
            account = Account.objects.get(username=username)
        except:
            return username
        raise forms.ValidationError(f"email{username} is already in use.")

        user = self.model(
            email=self.normalize_email(email),
            username=username,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password):
        user = self.create_user(
            email=self.normalize_email(email),
            password=password,
            username=username,
        )
        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Godda