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

Validation messages not always showing #27729

Closed
DanielMalmgren opened this issue Mar 1, 2019 · 37 comments
Closed

Validation messages not always showing #27729

DanielMalmgren opened this issue Mar 1, 2019 · 37 comments

Comments

@DanielMalmgren
Copy link

  • Laravel Version: 5.8.2
  • PHP Version: 7.2.15
  • Database Driver & Version: 5.7.25

Description:

I've got some kind of strange race condition here... I have got a form posting to Laravel. The function receiving the post currently looks like this:

    public function store(Request $request, Workplace $workplace) {
        usleep(50000);
        $request->validate(
            [
                'starttime' => 'required',
                'endtime' => 'required|after:starttime',
                'date' => 'required',
                'workplace_id' => 'required'
            ],
            [
            'starttime.required' => __('Du måste ange en starttid!'),
            'endtime.required' => __('Du måste ange en sluttid!'),
            'date.required' => __('Du måste ange ett datum!'),
            'endtime.after' => __('Sluttiden får inte inträffa före starttiden!')
        ]);

        //Removed code to save stuff to db, not relevant here

        return redirect('/')->with('success', 'Projekttiden har registrerats');
    }

The strange thing here is that if I remove the first line (the delay), my error messages only pops up in the browser sometimes, like one time in two (seemingly randomly distributed). Discovered this first by adding a debug log output, which obviously took enough time for things to work... The validation always works (ie the code after the validate() call don't get executed) but the user gets no notification about what's wrong.

Anyone seen this before?

This happened also in Laravel 5.7, just never got around to report it. Now on 5.8. Happens both on my dev machine (hyperv Homestead) and production machine (Ubuntu 18.04).

I don't know if it's relevant, but here's my code for displaying the errors:

@if($errors->any())
    @foreach($errors->all() as $error)
        <div class="alert alert-danger">
            {{$error}}
        </div>
    @endforeach
@endif

@if(session('success'))
    <div class="alert alert-success">
        {{session('success')}}
    </div>
@endif

@if(session('error'))
    <div class="alert alert-danger">
        {{session('error')}}
    </div>
@endif
@ManojKiranA
Copy link
Contributor

ManojKiranA commented Mar 1, 2019

what is your is issue You are facing

Are You getting the

Validation failure but no error message OR

Validation success and data is being processed

@staudenmeir
Copy link
Contributor

Can you reproduce this on a fresh installation of Laravel?

@DanielMalmgren
Copy link
Author

ManojKiranA: I really don't understand your question... The validation succeeds, but sometimes the error messages doesn't contain anything.

staudenmeir: Good question. Haven't tried that. Guess it could be worth testing.

Btw, I have now also tried simply dd:ing $errors and when the error messages don't display, the errorbag is definitely empty.

Also, forgot to mention in the original report, I've tried with a custom FormRequest as well, gives the exact same behaviour.

@ManojKiranA
Copy link
Contributor

try this create file named as flash-message.blade.php in projectname/resource/views/

and paste the following code into it

@if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
	<button type="button" class="close" data-dismiss="alert">×</button>	
        <strong>{{ $message }}</strong>
</div>
@endif


@if ($message = Session::get('error'))
<div class="alert alert-danger alert-block">
	<button type="button" class="close" data-dismiss="alert">×</button>	
        <strong>{{ $message }}</strong>
</div>
@endif


@if ($message = Session::get('warning'))
<div class="alert alert-warning alert-block">
	<button type="button" class="close" data-dismiss="alert">×</button>	
	<strong>{{ $message }}</strong>
</div>
@endif


@if ($message = Session::get('info'))
<div class="alert alert-info alert-block">
	<button type="button" class="close" data-dismiss="alert">×</button>	
	<strong>{{ $message }}</strong>
</div>
@endif


@if ($errors->any())


<div class="alert alert-danger">
	<button type="button" class="close" data-dismiss="alert">x</button>	
	Please check the form below for errors
</div>
@endif

@if ($errors->any())

<div class="alert alert-danger">
	<button type="button" class="close" data-dismiss="alert">x</button>	
	{{ implode('', $errors->all(':message')) }}
</div>


@endif

Now Open Your projectname/resource/views/layouts/app.blade.php

and incude that @include('flash-message')

and you will get something please comment the result

@ManojKiranA
Copy link
Contributor

ManojKiranA commented Mar 1, 2019

Can you reproduce this on a fresh installation of Laravel?

its not the solution think a situation if he has done many modules in project

@DanielMalmgren
Copy link
Author

Ok, added that code. When the displaying of my own errors don't work that one doesn't either, but when my errors display I get the following:

Please check the form below for errors
Du måste ange en starttid!Du måste ange en sluttid!Du måste ange ett datum!

I think this leads to the same conclusion as all other tests I've done: Sometimes there are no errors produced even though the validation fails. Since a short delay in the store function makes things work it must have something to do with the $errors array not being populated fast enough. Don't know enough about the inner workings to understand exactly what's happening though...

@ManojKiranA
Copy link
Contributor

Have You tried FormRequest

@DanielMalmgren
Copy link
Author

Yep. Mentioned that above. Makes no difference.

@ManojKiranA
Copy link
Contributor

try the Validator Facade Method

public function store(Request $request, Workplace $workplace) {
    {       
        $input = $request->all();
        $validator = \Validator::make(
            $request->all(), 
                [
                    'starttime' => 'required',
                    'endtime' => 'required|after:starttime',
                    'date' => 'required',
                    'workplace_id' => 'required'
                ],

                [
                    'starttime.required' => __('Du måste ange en starttid!'),
                    'endtime.required' => __('Du måste ange en sluttid!'),
                    'date.required' => __('Du måste ange ett datum!'),
                    'endtime.after' => __('Sluttiden får inte inträffa före starttiden!')
                ]

        );

        if ($validator->fails()) {
                  return redirect()->back()
                                  ->withErrors($validator)
                                  ->withInput($input);
        }
     return redirect('/')->with('success', 'Projekttiden har registrerats');
    }

@DanielMalmgren
Copy link
Author

Nope, that gives the same problem :-(

@rs-sliske
Copy link

do you have your app open in another tab that could be affecting your session?

@devcircus
Copy link
Contributor

May not be the case here, but the answer usually resides in the code deemed "irrelevant".

@DanielMalmgren
Copy link
Author

rs-sliske: Nope, only one tab open.

devcircus: The code I deemed as irrelevant is never reached at all, since the validation fails. Verified that by a logger() call as the first row after the validation.

@driesvints
Copy link
Member

@DanielMalmgren can you create an app with a minimum setup that re-creates the problem which we can test with?

@guccilive
Copy link

guccilive commented Mar 7, 2019

I'm facing the same issue. I even created two different fresh projects on 5.8 version but still facing the same problem with Validation customized message/rule or custom Request Class. No error, Not executing method after submit.
For example, this basic code:

`use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Controller;
use App\ModelAuth\Role;
use App\Http\Requests\AddUserRoleRequest;
use Carbon\Carbon;
use Session;

class UserRoleController extends Controller
{
    public function ShowRoleForm()
    {
        $roles = Role::all();
        return view('admin.setting.user-role', compact('roles'));
    }

public function AddUserNewRole( Request $req)
{
    $custom_message = [
        'name.required' => 'Le champ Nom est requis.',
        'name.unique' => 'Ce nom existe déjà.',
        'description.required' => 'Le champ Description est requis',
      ];
      $this->validate($req,[
        'name' => 'required|unique:roles',
        'description' => 'required',
      ], $custom_message);

    $roles = new Role;
    $roles->name = $req->name;
    $roles->description = $req->description;
    $roles->save();

    Session::flash('successMsg','Role ajouté avec succè!');
    return redirect()->back();
}

}`

Model:
`<?php

namespace App\ModelAuth;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class Role extends Model
{
    use Notifiable;
protected $fillable = ['name','description'];

protected $primaryKey ='id';

protected $table ='roles' ;

}
`

@driesvints
Copy link
Member

@DanielMalmgren @guccilive are you both still experiencing this?

@DanielMalmgren
Copy link
Author

Yep, the problem persists in 5.8.8. Haven't got any time for digging any deeper though, for now I'm just putting usleep() calls in the beginning of all my store functions.

@laurencei
Copy link
Contributor

@DanielMalmgren - what session driver are you using?

Can you try switching to a different session driver and trying again?

@DanielMalmgren
Copy link
Author

@laurencei Sorry, forgot to mention here. I'm normally using file session drivers, but I've already tried changing to database, didn't make any differene.

@laurencei
Copy link
Contributor

Is the form behind an auth page - i.e. do you need to be logged in to see it? The most common reason for failed validation messages is a session failure.

my dev machine (hyperv Homestead)

Homestead has Redis - try switching to a Redis session driver and see if it happens there? Both file + database are not true atomic storage.

@laurencei
Copy link
Contributor

Also @staudenmeir asked this a while ago:

Can you reproduce this on a fresh installation of Laravel?

to which you replied

Good question. Haven't tried that. Guess it could be worth testing.

The default Laravel install with default auth gives you a good starting point. Create a basic form and see if you can reproduce there. If not, slowly add stuff back in until the problem arises...

@DanielMalmgren
Copy link
Author

Is the form behind an auth page - i.e. do you need to be logged in to see it? The most common reason for failed validation messages is a session failure.

The entire site is behind SAML2 authentication (https://github.com/aacotroneo/laravel-saml2). I tried disabling authentication now though, going completely unauthenticated, and the problem persists.

my dev machine (hyperv Homestead)

Homestead has Redis - try switching to a Redis session driver and see if it happens there? Both file + database are not true atomic storage.

Ok, tried redis too. Same problem.

The default Laravel install with default auth gives you a good starting point. Create a basic form and see if you can reproduce there. If not, slowly add stuff back in until the problem arises...

Yep, I guess this is the next time to test. Too tight schedule currently though, guess this will need to hang in the air until I get time to test.

@laurencei
Copy link
Contributor

Essentially it has to boil down to one of two things:

  1. If you can create this on a basic install of Laravel with no other code changes, then it is somehow related to your environment, infrastructure etc.

  2. If you cannot re-create this on a basic Laravel; then something in your code is interfering with the internal code and causing the bug.

Either way, it's fairly safe to say this is not Laravel specific at this point in time. It's not reproducible for anyone else with the scenario you've given. The only thing I can think of is some strange environment setup that causes an edge case, in which situation that might be a Laravel bug. But until you can point it down one way or the other, there's not much we can do here.

Once you track it down, ping us and we can reopen this with new information.

@Adam-78
Copy link

Adam-78 commented Apr 27, 2019

I've just upgraded to laravel 5.8 from 5.7 and I've noticed the same issue. Validation works i.e user is redirected to the form page but no validation messages are showing.

@jereconjota
Copy link

any solutions? i have same issue
v5.8.28

@DanielMalmgren
Copy link
Author

I never found any solution. There's obviously a bug here somewhere but I haven't succeeded in proving exactly where, so for the time being I'm living with usleep() calls the first thing in all my store, update and destroy methods. I don't know though if any devs are still reading here now that the ticket is closed?

@devcircus
Copy link
Contributor

Like was mentioned already, the best way to track it down to a bug in your code or a hug in the framework is to create a new laravel app and only add the relevant code for showing the error messages. If the bug persists in a new app, push that app to github so the community can help.

@aline-matos
Copy link

Same issue, v5.8.28, with redis:

return redirect()->route('login')->with('error', 'The credentials do not match our records');
Array (
    [_token] => osjrWEce4fVzbg4XJtqvr1JeTBfhViputIqkv7qd
    [_previous] => Array (
            [url] => http://127.0.0.1:8001/login
        )
    [_flash] => Array (
            [old] => Array ( )
            [new] => Array ( )
        )
)

@jereconjota
Copy link

I never found any solution. you had lucky?

@jereconjota
Copy link

I solved this problem by changing xampp to mamp

@binaryhq
Copy link

This might help.

https://stackoverflow.com/a/59420073/3738033

@oza75
Copy link

oza75 commented Feb 12, 2020

Moving \Illuminate\Session\Middleware\StartSession::class and \Illuminate\View\Middleware\ShareErrorsFromSession::class from web $middlewareGroups to $middleware in app\Http\Kernel.php solve this issue !

But I don't know if this can cause unexpected behavior on Api routes

@utkubasaran
Copy link

use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;

public function store(Request $request) {

        $input = $request->all();

        $validator = Validator::make(
            $request->all(),
            [
                'name' => 'required|max:255',
            ],
            [
                'name.required' => 'your message here'
            ]
        );


        if ($validator->fails()) {
            return redirect('/')
                ->withInput($input)
                ->withErrors($validator);
        }
    }

@almirhodzic
Copy link

I having the exact same problem here! Laravel 9.28 on xampp 8.1.6 -> Win10. Did anyone found a solution?

@almirhodzic
Copy link

I having the exact same problem here! Laravel 9.28 on xampp 8.1.6 -> Win10. Did anyone found a solution?

Found the bug, in livewire.php configfile, the Assets and App_url was wrong pointed.

@tiagoskaterock
Copy link

I've started a new Laravel project about 1 month ago and I am facing this problem too.

Sometimes Laravel Validation works fine, but in others they simply go back to the form and does not show the errors.

I test the same error many times, and it look like it only works properly whenever it wants.

It's like it works fine and show the errors 2 or 3 times and then on the next test it shows just a list with no errors, even the validation working nice.

I am reading a lot of forums about that but in no place I found the answer.

The flash message are also the same way, sometime it works and sometimes don't.

I don't know if it is my computer, or OS, or browser, Laravel version, extensions, or whatever...

Using Chrome and Ubuntu 18.04

@FabianoLothor
Copy link

FabianoLothor commented Feb 24, 2023

Jeez...

This one was pretty hard to figure out.

There are a lot of similar related issues what turns that very tricky.

I think here is the right thread to share what I found.


For instance, I'm working in a legacy system that was updated from Laravel 5.2 to 5.5 a few months ago, so keep in mind that your issue might be different.

Initially I thought that it could be due the settings of the middlewares, more about that in the links below:


After a few hours without success or anything really helpful, I decided to dig the old code with Laravel 5.2.

Well, they changed the behavior of ValidatesRequests trait. Not only, but mainly the function validate:

// 5.5
    public function validate(Request $request, array $rules,
                             array $messages = [], array $customAttributes = [])
    {
        $this->getValidationFactory()
             ->make($request->all(), $rules, $messages, $customAttributes)
             ->validate();

        return $this->extractInputFromRules($request, $rules);
    }
// 5.2 - I didn't look carefully, but it seems that wasn't changed until 5.4
    public function validate(Request $request, array $rules, array $messages = [], array $customAttributes = [])
    {
        $validator = $this->getValidationFactory()->make($request->all(), $rules, $messages, $customAttributes);

        if ($validator->fails()) {
            $this->throwValidationException($request, $validator);
        }
    }

After figured out that, I went back to the docs and didn't find anything related to that.

image

Anyway, it seems that after 5.5 if you want to send the errors and the inputs to the view, instead of only do return back();, you will need to use something like return back()->withInput()->withErrors($exception->validator ?? '');.

Alternatively,you can create a custom trait using the old code from 5.2 (perhaps combine both) and override the uses of ValidatesRequests to CustomValidatesRequests.

After recover the trait from 5.2, the error messages came back to the system. 😃

Despite of that, keep in mind this might cause other issues, if possible it's better to use ->withInput()->withErrors($exception->validator ?? '');.

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

No branches or pull requests