Closed Abhishek-Jetani closed 2 months ago
To fully debug this, you should also place the code on the frontend.
Either way, I think the transaction has nothing to do with the error showing on the frontend or not.
If you're coding in Laravel 11, you should refer to the documentation of Laravel 11 to do things.
There's an automatic redirection method, removes the necessity of the if you've placed to check if the validation has failed. https://laravel.com/docs/11.x/validation#automatic-redirection
Can you try this approach instead?
Hi, @hugoboss17
Thank you for the response.
I have already conducted extensive debugging on this issue, and unfortunately, the problem persists. The validation errors do not show up in the Blade view when DB::beginTransaction();
is placed above the validation logic, even when using the automatic redirection method as suggested in the Laravel 11 documentation.
I have tried the following:
Ensuring the validation is correctly set up as per the Laravel 11 documentation.
Utilizing the automatic redirection method as described here.
Debugging the frontend to confirm that the issue is not related to the Blade template.
Despite these efforts, the issue remains unresolved. The validation messages only display correctly when the transaction handling is adjusted as mentioned in my initial post.
Could you please provide further insights or confirm if there have been changes to the database methods in Laravel 11 that might affect this behavior?
Thank you.
Heya, thanks for reporting.
We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here? Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.
laravel new bug-report --github="--public"
Please do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.
Thanks!
Hello, @driesvints
I've created the repository as requested. The code that reproduces the issue is committed on the main branch. Please find the repository here: GitHub Repository Link.
Thank you for your assistance in resolving this issue!
Thank you for reporting this issue!
As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.
If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.
Thank you!
Hello @Abhishek-Jetani and @driesvints !
I'm taking a look on this and I cannot reproduce the error on the repository example. It's working:
Maybe I'm missing something.
Thank you!
Hello @alibori !
Thank you for checking the issue!
Just to clarify, I have implemented this code in an existing working project, and I've also created a new project to test it. Additionally, two of my friends have implemented the same code in their Laravel 11 versions. Unfortunately, we're all experiencing the same issue, where the validation messages do not display in the Blade view file when DB::beginTransaction()
is placed above the validation code.
Please let me know if there's any additional information I can provide.
Thank you!
Hello @Abhishek-Jetani @driesvints
I have thoroughly debugged the issue and found that it is not related to the Laravel framework itself.
In Laravel 10, the default SESSION_DRIVER in the .env file is set to file. This setup can cause an error when using DB::beginTransaction(), as the session errors are stored in files and subsequently displayed on the front end.
However, in Laravel 11, the .env file defaults to SESSION_DRIVER=database, which prevents this issue from appearing on the front end.
To replicate the issue from Laravel 10, you need to change SESSION_DRIVER=database to SESSION_DRIVER=file. This way, the error will be stored in the session and displayed on the front end as expected.
When using SESSION_DRIVER=file, the error messages are stored and can be accessed using $errors.
If SESSION_DRIVER=database is used, $errors will return an []empty array, but with file, it will return the correct error message in laravel 11.
(Database driver) e.g., [] (File Driver) e.g., {"first_name":["The first name field is required."]}.
Here is the Laravel 11 code example:
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_11
DB_USERNAME=root
DB_PASSWORD=root
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TestController;
Route::get('/', function () {
return view('welcome');
});
Route::post('/test', [TestController::class,'test'])->name('test');
App\Http\Controllers\TestController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class TestController extends Controller
{
public function test(Request $request)
{
try {
DB::beginTransaction();
$validator = Validator::make($request->all(), [
'first_name' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
DB::commit();
return redirect()->back()->with('success', 'success');
} catch (\Exception $e) {
info($e);
DB::rollBack();
return redirect()->back()->with('error', 'Something went wrong.');
}
}
}
resources\views\welcome.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Laravel 11 - Form Validation</title>
</head>
<body>
{{info($errors)}}
<h2>Laravel 11 - Form Validation</h2>
<form action="{{ route('test') }}" method="POST">
@csrf
<div class="form-group">
<label for="name">name:</label>
<input type="text" name="first_name" class="form-control" value="">
@error('first_name')
<div class="text-danger">{{ $message }}</div>
@enderror
</div></br>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</body>
</html>
Output
Please let me know if you need more information about it.
Thank you so much 😊
Hello @Abhishek-Jetani @driesvints
I have thoroughly debugged the issue and found that it is not related to the Laravel framework itself.
In Laravel 10, the default SESSION_DRIVER in the .env file is set to file. This setup can cause an error when using DB::beginTransaction(), as the session errors are stored in files and subsequently displayed on the front end.
However, in Laravel 11, the .env file defaults to SESSION_DRIVER=database, which prevents this issue from appearing on the front end.
To replicate the issue from Laravel 10, you need to change SESSION_DRIVER=database to SESSION_DRIVER=file. This way, the error will be stored in the session and displayed on the front end as expected.
When using SESSION_DRIVER=file, the error messages are stored and can be accessed using $errors.
If SESSION_DRIVER=database is used, $errors will return an []empty array, but with file, it will return the correct error message in laravel 11.
(Database driver) e.g., [] (File Driver) e.g., {"first_name":["The first name field is required."]}.
Here is the Laravel 11 code example:
.env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_11 DB_USERNAME=root DB_PASSWORD=root SESSION_DRIVER=file SESSION_LIFETIME=120 SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null
web.php
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TestController; Route::get('/', function () { return view('welcome'); }); Route::post('/test', [TestController::class,'test'])->name('test');
App\Http\Controllers\TestController
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; class TestController extends Controller { public function test(Request $request) { try { DB::beginTransaction(); $validator = Validator::make($request->all(), [ 'first_name' => 'required', ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); } DB::commit(); return redirect()->back()->with('success', 'success'); } catch (\Exception $e) { info($e); DB::rollBack(); return redirect()->back()->with('error', 'Something went wrong.'); } } }
resources\views\welcome.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Laravel 11 - Form Validation</title> </head> <body> {{info($errors)}} <h2>Laravel 11 - Form Validation</h2> <form action="{{ route('test') }}" method="POST"> @csrf <div class="form-group"> <label for="name">name:</label> <input type="text" name="first_name" class="form-control" value=""> @error('first_name') <div class="text-danger">{{ $message }}</div> @enderror </div></br> <button type="submit" class="btn btn-primary">Submit</button> </form> </body> </html>
Output
Read More: HTTP Session
Please let me know if you need more information about it.
Thank you so much 😊
Hi @keyurbhimani !
In my test project the error message is shown whether the value of the SESSION_DRIVER
variable is file
or database
.
@Abhishek-Jetani this solve your problem?
Hello @alibori !
Thank you for checking the issue!
Just to clarify, I have implemented this code in an existing working project, and I've also created a new project to test it. Additionally, two of my friends have implemented the same code in their Laravel 11 versions. Unfortunately, we're all experiencing the same issue, where the validation messages do not display in the Blade view file when
DB::beginTransaction()
is placed above the validation code.Please let me know if there's any additional information I can provide.
Thank you!
Hi @Abhishek-Jetani !
When DB::beginTransaction()
is executed before the validation and you submit the form is a Throwable $th
catched? If not, which value has $errors
or $error
?
Thanks in advance!
Hello @Abhishek-Jetani @driesvints
I have thoroughly debugged the issue and found that it is not related to the Laravel framework itself.
In Laravel 10, the default SESSION_DRIVER in the .env file is set to file. This setup can cause an error when using DB::beginTransaction(), as the session errors are stored in files and subsequently displayed on the front end.
However, in Laravel 11, the .env file defaults to SESSION_DRIVER=database, which prevents this issue from appearing on the front end.
To replicate the issue from Laravel 10, you need to change SESSION_DRIVER=database to SESSION_DRIVER=file. This way, the error will be stored in the session and displayed on the front end as expected.
When using SESSION_DRIVER=file, the error messages are stored and can be accessed using $errors.
If SESSION_DRIVER=database is used, $errors will return an []empty array, but with file, it will return the correct error message in laravel 11.
(Database driver) e.g., [] (File Driver) e.g., {"first_name":["The first name field is required."]}.
Here is the Laravel 11 code example:
.env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_11 DB_USERNAME=root DB_PASSWORD=root SESSION_DRIVER=file SESSION_LIFETIME=120 SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null
web.php
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TestController; Route::get('/', function () { return view('welcome'); }); Route::post('/test', [TestController::class,'test'])->name('test');
App\Http\Controllers\TestController
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; class TestController extends Controller { public function test(Request $request) { try { DB::beginTransaction(); $validator = Validator::make($request->all(), [ 'first_name' => 'required', ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); } DB::commit(); return redirect()->back()->with('success', 'success'); } catch (\Exception $e) { info($e); DB::rollBack(); return redirect()->back()->with('error', 'Something went wrong.'); } } }
resources\views\welcome.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Laravel 11 - Form Validation</title> </head> <body> {{info($errors)}} <h2>Laravel 11 - Form Validation</h2> <form action="{{ route('test') }}" method="POST"> @csrf <div class="form-group"> <label for="name">name:</label> <input type="text" name="first_name" class="form-control" value=""> @error('first_name') <div class="text-danger">{{ $message }}</div> @enderror </div></br> <button type="submit" class="btn btn-primary">Submit</button> </form> </body> </html>
Output
Read More: HTTP Session
Please let me know if you need more information about it.
Thank you so much 😊
Hi @keyurbhimani ,
Thank you so much for the detailed explanation and code example! I implemented the changes you suggested by switching the SESSION_DRIVER to file, and it's working perfectly now. The validation messages are displaying as expected.
I really appreciate your help with this!
Thanks again 😊
Hello @Abhishek-Jetani @driesvints I have thoroughly debugged the issue and found that it is not related to the Laravel framework itself. In Laravel 10, the default SESSION_DRIVER in the .env file is set to file. This setup can cause an error when using DB::beginTransaction(), as the session errors are stored in files and subsequently displayed on the front end. However, in Laravel 11, the .env file defaults to SESSION_DRIVER=database, which prevents this issue from appearing on the front end. To replicate the issue from Laravel 10, you need to change SESSION_DRIVER=database to SESSION_DRIVER=file. This way, the error will be stored in the session and displayed on the front end as expected. When using SESSION_DRIVER=file, the error messages are stored and can be accessed using $errors. If SESSION_DRIVER=database is used, $errors will return an []empty array, but with file, it will return the correct error message in laravel 11. (Database driver) e.g., [] (File Driver) e.g., {"first_name":["The first name field is required."]}. Here is the Laravel 11 code example: .env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_11 DB_USERNAME=root DB_PASSWORD=root SESSION_DRIVER=file SESSION_LIFETIME=120 SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null
web.php
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TestController; Route::get('/', function () { return view('welcome'); }); Route::post('/test', [TestController::class,'test'])->name('test');
App\Http\Controllers\TestController
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; class TestController extends Controller { public function test(Request $request) { try { DB::beginTransaction(); $validator = Validator::make($request->all(), [ 'first_name' => 'required', ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); } DB::commit(); return redirect()->back()->with('success', 'success'); } catch (\Exception $e) { info($e); DB::rollBack(); return redirect()->back()->with('error', 'Something went wrong.'); } } }
resources\views\welcome.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Laravel 11 - Form Validation</title> </head> <body> {{info($errors)}} <h2>Laravel 11 - Form Validation</h2> <form action="{{ route('test') }}" method="POST"> @csrf <div class="form-group"> <label for="name">name:</label> <input type="text" name="first_name" class="form-control" value=""> @error('first_name') <div class="text-danger">{{ $message }}</div> @enderror </div></br> <button type="submit" class="btn btn-primary">Submit</button> </form> </body> </html>
Output
Read More: HTTP Session
Please let me know if you need more information about it. Thank you so much 😊
Hi @keyurbhimani !
In my test project the error message is shown whether the value of the
SESSION_DRIVER
variable isfile
ordatabase
.@Abhishek-Jetani this solve your problem?
Hello @Abhishek-Jetani @driesvints I have thoroughly debugged the issue and found that it is not related to the Laravel framework itself. In Laravel 10, the default SESSION_DRIVER in the .env file is set to file. This setup can cause an error when using DB::beginTransaction(), as the session errors are stored in files and subsequently displayed on the front end. However, in Laravel 11, the .env file defaults to SESSION_DRIVER=database, which prevents this issue from appearing on the front end. To replicate the issue from Laravel 10, you need to change SESSION_DRIVER=database to SESSION_DRIVER=file. This way, the error will be stored in the session and displayed on the front end as expected. When using SESSION_DRIVER=file, the error messages are stored and can be accessed using $errors. If SESSION_DRIVER=database is used, $errors will return an []empty array, but with file, it will return the correct error message in laravel 11. (Database driver) e.g., [] (File Driver) e.g., {"first_name":["The first name field is required."]}. Here is the Laravel 11 code example: .env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_11 DB_USERNAME=root DB_PASSWORD=root SESSION_DRIVER=file SESSION_LIFETIME=120 SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null
web.php
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TestController; Route::get('/', function () { return view('welcome'); }); Route::post('/test', [TestController::class,'test'])->name('test');
App\Http\Controllers\TestController
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; class TestController extends Controller { public function test(Request $request) { try { DB::beginTransaction(); $validator = Validator::make($request->all(), [ 'first_name' => 'required', ]); if ($validator->fails()) { return redirect()->back()->withErrors($validator)->withInput(); } DB::commit(); return redirect()->back()->with('success', 'success'); } catch (\Exception $e) { info($e); DB::rollBack(); return redirect()->back()->with('error', 'Something went wrong.'); } } }
resources\views\welcome.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Laravel 11 - Form Validation</title> </head> <body> {{info($errors)}} <h2>Laravel 11 - Form Validation</h2> <form action="{{ route('test') }}" method="POST"> @csrf <div class="form-group"> <label for="name">name:</label> <input type="text" name="first_name" class="form-control" value=""> @error('first_name') <div class="text-danger">{{ $message }}</div> @enderror </div></br> <button type="submit" class="btn btn-primary">Submit</button> </form> </body> </html>
Output
Read More: HTTP Session
Please let me know if you need more information about it. Thank you so much 😊
Hi @keyurbhimani !
In my test project the error message is shown whether the value of the
SESSION_DRIVER
variable isfile
ordatabase
.@Abhishek-Jetani this solve your problem?
Hello @alibori,
Yes, the problem is resolved. After changing the SESSION_DRIVER value from database to file in the .env file, everything is working perfectly for me.
Thank you for checking in!
Hello @alibori ! Thank you for checking the issue! Just to clarify, I have implemented this code in an existing working project, and I've also created a new project to test it. Additionally, two of my friends have implemented the same code in their Laravel 11 versions. Unfortunately, we're all experiencing the same issue, where the validation messages do not display in the Blade view file when
DB::beginTransaction()
is placed above the validation code. Please let me know if there's any additional information I can provide. Thank you!Hi @Abhishek-Jetani !
When
DB::beginTransaction()
is executed before the validation and you submit the form is aThrowable $th
catched? If not, which value has$errors
or$error
?Thanks in advance!
Hi @alibori,
Thanks for the follow-up. I checked the logs, and when DB::beginTransaction()
is executed before the validation, no exception is caught in the catch block.
However, the validation fails as expected, and the $errors variable contains the following:
{"errors":{"Illuminate\\Support\\MessageBag":{"name":["The name field is required."]}}}
So, the validation errors are correctly identified, but they aren't displayed in the Blade view as expected when using the database session driver.
Here's the controller code I used for this test:
`public function testForm(Request $request)
{
try {
DB::beginTransaction();
$validator = Validator::make($request->all(), [
'name' => 'required',
]);
if ($validator->fails()) {
// Debugging: Log or inspect the value of $errors
info('Validation failed, $errors:', ['errors' => $validator->errors()]);
return redirect()->back()->withErrors($validator)->withInput();
}
User::create(['name' => $request->name]);
DB::commit();
return redirect()->back()->with('success', 'success');
} catch (\Throwable $th) {
// Debugging: Log the throwable to see if it's caught
report($th);
info('Exception caught in catch block:', ['exception' => $th]);
DB::rollBack();
return redirect()->back()->with('error', 'Something went wrong.');
}
}
`
Let me know if you need any more information.
Thanks again!
Hello @alibori ! Thank you for checking the issue! Just to clarify, I have implemented this code in an existing working project, and I've also created a new project to test it. Additionally, two of my friends have implemented the same code in their Laravel 11 versions. Unfortunately, we're all experiencing the same issue, where the validation messages do not display in the Blade view file when
DB::beginTransaction()
is placed above the validation code. Please let me know if there's any additional information I can provide. Thank you!Hi @Abhishek-Jetani ! When
DB::beginTransaction()
is executed before the validation and you submit the form is aThrowable $th
catched? If not, which value has$errors
or$error
? Thanks in advance!Hi @alibori,
Thanks for the follow-up. I checked the logs, and when
DB::beginTransaction()
is executed before the validation, no exception is caught in the catch block.However, the validation fails as expected, and the $errors variable contains the following:
{"errors":{"Illuminate\\Support\\MessageBag":{"name":["The name field is required."]}}}
So, the validation errors are correctly identified, but they aren't displayed in the Blade view as expected when using the database session driver.
Here's the controller code I used for this test:
`public function testForm(Request $request) { try { DB::beginTransaction(); $validator = Validator::make($request->all(), [ 'name' => 'required', ]); if ($validator->fails()) { // Debugging: Log or inspect the value of $errors info('Validation failed, $errors:', ['errors' => $validator->errors()]); return redirect()->back()->withErrors($validator)->withInput(); } User::create(['name' => $request->name]); DB::commit(); return redirect()->back()->with('success', 'success'); } catch (\Throwable $th) { // Debugging: Log the throwable to see if it's caught report($th); info('Exception caught in catch block:', ['exception' => $th]); DB::rollBack(); return redirect()->back()->with('error', 'Something went wrong.'); } } `
Let me know if you need any more information.
Thanks again!
Hi @Abhishek-Jetani !
To be honest I don't know why is this happening. Do you have the sessions table on your database, right?
As far as I know the session's driver only defines where the session's data will be stored, so this should work with the database one too...
Anyway, happy to hear that your problem seems to be solved!
Regards
The issue has been resolved. The problem was in the .env
file, where changing the SESSION_DRIVER
value from database
to file
fixed the issue for me.
Thank you to everyone who helped!
Laravel Version
11.15.0
PHP Version
8.2.0
Database Driver & Version
Mysql & 5.2.0
Description
In Laravel 10 and previous versions, the following code worked perfectly without any issues. However, in Laravel 11, I encountered a problem when using database transactions with validation.
Issue:
When I add
DB::beginTransaction();
above the validation code, the validation messages do not display in the Blade view file.Steps To Reproduce
Add
DB::beginTransaction();
before the validation logic.Perform validation.
If validation fails, the error messages do not show up in the Blade view file.
Non-working Code:
Solutions:
Solution 1: Adding
DB::rollBack();
above the redirect statement with errors works.Solution 2: Moving
DB::beginTransaction();
after handling validation errors works perfectly.Question: Is this a bug in Laravel 11, or have there been any changes to the database methods that could cause this issue? This code works without any issues in Laravel 10 and previous versions.
Thank you for your time and assistance.
@taylorotwell @nunomaduro