laravellaravel-mail

Laravel redirect occasionally causing error 500 after email being sent


I have a weird issue with laravel redirect() after mailer function being executed in my controller for contact-us functionality. It sometimes returns server error 500 and the log says

"[2024-02-25 16:53:40] production.ERROR: No application encryption key has been specified. {"exception":"[object] (Illuminate\Encryption\MissingAppKeyException(code: 0): No application encryption key has been specified. at C:\xampp\htdocs\globus-transfers\vendor\laravel\framework\src\Illuminate\Encryption\EncryptionServiceProvider.php:79)"

This is nonsense because i have a working app key. The issue is gone if i use view instead of redirect but i do not understand why

This is the code i am having trouble with:

<?php

namespace App\Http\Controllers;

use App\Mail\ContactMail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class ContactController extends Controller
{
    public function show()
    {
        return view('contact');
    }

    public function send(Request $request)
    {
        // Validate the input
        $request->validate([
            'contact_full_name' => 'required|string|max:255',
            'contact_email' => 'required|email|max:255',
            'contact_phone' => 'required|string|max:20',
            'contact_message' => 'required|string',
        ]);

        // Send mail to the company
        Mail::to(env('MAIL_FROM_ADDRESS'))->send(new ContactMail($request));
        
        // return view('contact', ['message' => 'Your message has been sent. We will get back to you soon.']);
        return redirect()->route('contact.show')->with('message', 'Your message has been sent. We will get back to you soon.');
    }
}

If i use view function everything goes well the only downside is user being able to resubmit the data on page refresh and i don't want that. And if i comment out the mailer line redirect works without issues so there is something with the relationship between mailer and redirect method...

This is also my form that sends request to the ContactController :

<form method="post" action="{{ route('contact.send') }}" class="lg:col-span-4 space-y-4">
        @csrf
        <div class="flex flex-col space-y-2">
            <label for="contact_full_name">YOUR NAME *</label>
            <input type="text" name="contact_full_name" id="contact_full_name" class="border-2 w-full rounded p-2" required>
        </div>
        <div class="flex flex-col space-y-2">
            <label for="contact_email">EMAIL ADDRESS *</label>
            <input type="contact_email" name="contact_email" id="contact_email" class="border-2 w-full rounded p-2" required>
        </div>
        <div class="flex flex-col space-y-2">
            <label for="contact_phone">PHONE *</label>
            <input type="text" name="contact_phone" id="contact_phone" class="border-2 w-full rounded p-2" required>
        </div>
        <div class="flex flex-col space-y-2">
            <label for="contact_message" class="">MESSAGE *</label>
            <textarea name="contact_message" class="input-text w-full border-2 p-2 rounded" id="contact_message" rows="5">{{old('contact_message')}}</textarea>
        </div>
        <div class="text-end">
            <button type="submit" class="py-3 px-5 bg-amber-500 transition hover:bg-amber-600 text-white rounded">SEND MESSAGE</button>
        </div>
    </form>

And these are my routes :

Route::get('/contact', [ContactController::class, 'show'])- 
>name('contact.show');
Route::post('/contact', [ContactController::class, 'send'])- 
>name('contact.send');

I also have to mention beside error 500 i get error 419 page expired occasionally too but mailer works in every case without any problem just redirect() fails sometimes. Weird indeed.


Solution

  • This is my current workaround and it works fine, i used view() helper function instead of redirect() to refresh the contact page after form submission. If user refreshes the page again it will ask him to resubmit but for that reason his data will be stored in the session and if the resubmitted data is equal to the one stored in the session it returns an error :

        <?php
    
        namespace App\Http\Controllers;
    
        use App\Mail\ContactMail;
        use Illuminate\Http\Request;
        use Illuminate\Support\Facades\Mail;
        use Illuminate\Support\Facades\Session;
    
    
        class ContactController extends Controller
        {
        public function show()
        {
            return view('contact');
        }
    
        public function send(Request $request)
        {
            // Check if the order has already been confirmed
            if (
                session()->has('message_sent') && 
                session('contactData.contact_full_name') == $request- 
       >input('contact_full_name') &&
                session('contactData.contact_email') == $request- 
       >input('contact_email') &&
                session('contactData.contact_phone') == $request- 
       >input('contact_phone') &&
                session('contactData.contact_message') == $request- 
       >input('contact_message')
            ) {
                return response()->json(['error' => 'Message has already been 
        sent.'], 400);
            }
            // Validate the input
            $request->validate([
                'contact_full_name' => 'required|string|max:255',
                'contact_email' => 'required|email|max:255',
                'contact_phone' => 'required|string|max:20',
                'contact_message' => 'required|string',
            ]);
    
            // Mark the order as confirmed in the session
            session(['message_sent' => true]);
            Session::put('contactData', [
                'contact_full_name' => $request->input('contact_full_name'),
                'contact_email' => $request->input('contact_email'),
                'contact_phone' => $request->input('contact_phone'),
                'contact_message' => $request->input('contact_message')
            ]);
    
            // Send mail to the company
            Mail::to(env('MAIL_FROM_ADDRESS'))->send(new 
        ContactMail($request));
            
            return view('contact', ['message' => 'Your message has been sent. 
        We will get back to you soon.']);
        }
        }