Laravel 6.10 Application works locally but fails on production server with "Target class [] does not exist."

679 views Asked by At

This problem deals specifically with Laravel 6.10 and queue processing. On my local machine, the program runs fine, and all queued jobs load well and process to completion. On my GoDaddy server, I get a mysterious error when the job tries to load that reads:

Error thrown on line 805 in /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php with message:
    Target class [] does not exist.

Trace:
#0 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(681): Illuminate\Container\Container->build(NULL)
#1 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(629): Illuminate\Container\Container->resolve(NULL, Array)
#2 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(776): Illuminate\Container\Container->make(NULL, Array)
#3 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(215): Illuminate\Foundation\Application->make(NULL)
#4 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\Jobs\Job->resolve(NULL)
#5 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(354): Illuminate\Queue\Jobs\Job->fire()
#6 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(300): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#7 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#8 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\Queue\Worker->daemon('database', 'default', Object(Illuminate\Queue\WorkerOptions))
#9 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default')
#10 [internal function]: Illuminate\Queue\Console\WorkCommand->handle()
#11 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#12 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Util.php(36): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#13 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#14 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#15 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#16 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Console/Command.php(201): Illuminate\Container\Container->call(Array)
#17 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Command/Command.php(255): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#18 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Console/Command.php(188): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#19 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Application.php(1011): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Application.php(272): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 /home/jaredclemence/public_html/theninjaassistant.com/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#23 /home/jaredclemence/public_html/theninjaassistant.com/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#24 /home/jaredclemence/public_html/theninjaassistant.com/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#25 {main}

I believe the problem starts and will be solved by fixing the trace at item #4 where the following is called: Illuminate\Queue\Jobs\Job->resolve(NULL). I see this in both failing jobs on the GoDaddy server, but it does not happen in local. I don't know enough about laravel to understand where the NULL value is coming from and how to fix it. This occurs before the job class is loaded, but it does not happen for all queued jobs. Only jobs of this class.

In both the local copy and the production copy I use the GoDaddy databases, so both systems talk to the same database host. I use a database named CMP_dev and CMP_core to differentiate between the development and production tables. Because I am using the same database source, I can rule out changes in the mysql settings.

I upgraded all composer packages and retested. Then, I committed the composer.lock file and updated the GoDaddy server to match. So, I can rule out problems with old buggy code that have already been fixed by someone else.

The PHP version on the server is 7.3.11, and the PHP version on local dev is 7.3.6. The good news is that they are both 7.3.X, which reduces risk of language variations, but there still may be an issue between 7.3.6 and 7.3.11, but GoDaddy does not allow me to control the PHP setting beyond the minor version number of 7.3.

---- Added on January 09, 2020------ I thought it might be the difference in web servers. On my local machine, I use php artisan serve to host the software. On GoDaddy, I use Nginx. However, then I realized that it is not the server that runs the queue. The command line runs the queue, and both commands are being run using php artisan schedule:run. This rules out the web server software and all its components. ---------

I have successfully run queued mail jobs, which means that the queue works. This should localize the issue to the two classes that are generating problems for me. If I can find the issue with one, I will likely find the issue with the second, so I will include the first job causing issue here:

app/Jobs/ConvertCsvFileToIntermediateFile.php:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\ContactCsvFile;
use Illuminate\Support\Facades\Log;

class ConvertCsvFileToIntermediateFile implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $timeout = 500;

    /** @var ContactCsvFile */
    private $file;
    private $delegate;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(ContactCsvFile $file, $delegate = null)
    {
        $this->file = $file;
        $this->delegate = $delegate;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $this->file->process($this->delegate);
    }

}

The error is occurring before handle() is ever called. I know this because, when I include a dd($this->file) as the first line of handle, the line is never reached.

Also, I think it is important to note that when most jobs fail, their class name is listed in the queue:failed table. But in this case, the queue:failed table reads the time: "2020-01-08 09:23:23."

+----+------------+---------+---------------------+-----------+  
| ID | Connection | Queue   | Class               | Failed At |  
+----+------------+---------+---------------------+-----------+   
| 2  | database   | default | 2020-01-08 09:23:23 |           |   
+----+------------+---------+---------------------+-----------+   
2

There are 2 answers

0
Jared Clemence On BEST ANSWER

I still do not know what the meaning of the error is or how to fix it. However, I found a way around the issue, which I will describe here in case it helps any others with this problem.

I began to suspect that the strange database entries that appeared in the queue:failed table were an indication that something terrible happened to cause the program to fail during execution, which maybe led to a partial write to the database. This does not make sense to me as a logical solution since I have the jobs running within a transaction that should roll back on failure.

That being said, I looked at a potential memory bloat issue and a timeout issue. I've been having trouble with the timeouts, but the classes are already set for public $timeout = 500;, which should guarantee a full 500 seconds before the job fails (These jobs were failing in less than one minute). Even though the class allows for 500 seconds, GoDaddy can limit the amount of time that a process runs, so it is possible that the process took too long.

GoDaddy can also limit the amount of memory allowed to each process. Since the jobs worked on large arrays of data, it is possible that the length of time issue and the memory bloat issue could be solved by creating one job for each item instead of creating one job to iterate the array.

This is how I solved the problem. I did create a job that processed just one item. Instead of sending the whole array to one job, I iterated the array and sent each item to a job. I thought that this would increase the amount of time it took for the system to process each item, since the program has to bootstrap the application for each job as it loads, and now I have hundreds of jobs instead of one. However, if the total time increased, the time to process a single job would certainly decrease, because the job only processed a single item and then closed. Once I made this change, the GoDaddy server stopped throwing the NULL errors, and everything ran well.

I was also surprised to see that the smaller jobs also completed faster than the single job with the array. Even though the system had to bootstrap the application on each job, the system ran much faster when memory was not overloaded.

2
Ehab Abosuhi On

You have to read laravel 6.10 release notes.. Some functions deprecated and fixes. I think you have to add php unit 9 instead of v8 not supported and add it to composer required not dev