Open Bibendus83 opened 4 years ago
Here is an additional test I just made.
I tried adding the UsesTenantConnection
trait to the library QCod\Settings\Setting\Setting.php
that extends Model
and the error is fixed.
Obviously I can't change my vendor libraries but it should help with the debug of the issue.
I tried forcing the tenant connection with the setting in tenancy.php
but it doesn't work
'force-tenant-connection-of-models' => [
\QCod\Settings\Setting\Setting::class,
],
Can you provide us with a full stacktrace of the error? :)
The error I reported on my first post is the only thing that appears on my logs and it doesn't give me the stack trace, how do you get a full stack trace on a queue job error?
Edit: I was able to manually get the stack trace catching the job exception, here it is:
local.INFO:
#0 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Connection.php(624): Illuminate\Database\Connection->runQueryCallback('select `val`, `...', Array, Object(Closure))
#1 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Connection.php(333): Illuminate\Database\Connection->run('select `val`, `...', Array, Object(Closure))
#2 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2130): Illuminate\Database\Connection->select('select `val`, `...', Array, true)
#3 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2324): Illuminate\Database\Query\Builder->runSelect()
#4 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2604): Illuminate\Database\Query\Builder->Illuminate\Database\Query\{closure}()
#5 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2326): Illuminate\Database\Query\Builder->onceWithColumns(Array, Object(Closure))
#6 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(717): Illuminate\Database\Query\Builder->pluck('val', 'name')
#7 /shared/httpd/my-app/vendor/qcod/laravel-settings/src/Setting/SettingEloquentStorage.php(34): Illuminate\Database\Eloquent\Builder->pluck('val', 'name')
#8 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(418): QCod\Settings\Setting\SettingEloquentStorage->QCod\Settings\Setting\{closure}()
#9 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php(357): Illuminate\Cache\Repository->rememberForever('app_settings.de...', Object(Closure))
#10 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(239): Illuminate\Cache\CacheManager->__call('rememberForever', Array)
#11 /shared/httpd/my-app/vendor/qcod/laravel-settings/src/Setting/SettingEloquentStorage.php(35): Illuminate\Support\Facades\Facade::__callStatic('rememberForever', Array)
#12 /shared/httpd/my-app/vendor/qcod/laravel-settings/src/Setting/SettingEloquentStorage.php(43): QCod\Settings\Setting\SettingEloquentStorage->all(false)
#13 /shared/httpd/my-app/vendor/qcod/laravel-app-settings/src/Setting/AppSettings.php(60): QCod\Settings\Setting\SettingEloquentStorage->get('api_url', 'https://XXXXXXX...')
#14 /shared/httpd/my-app/vendor/qcod/laravel-app-settings/src/helpers.php(24): QCod\AppSettings\Setting\AppSettings->get('api_url', 'UNSET_OAUTH_SER...')
#15 /shared/httpd/my-app/app/Services/BookingApiConnection.php(23): setting('api_url', 'UNSET_OAUTH_SER...')
#16 [internal function]: App\Services\BookingApiConnection->__construct(true)
#17 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php(825): ReflectionClass->newInstanceArgs(Array)
#18 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php(667): Illuminate\Container\Container->build('App\\Services\\Bo...')
#19 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php(615): Illuminate\Container\Container->resolve('App\\Services\\Bo...', Array)
#20 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(767): Illuminate\Container\Container->make('App\\Services\\Bo...', Array)
#21 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(121): Illuminate\Foundation\Application->make('App\\Services\\Bo...', Array)
#22 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(733): app('App\\Services\\Bo...', Array)
#23 /shared/httpd/my-app/app/Models/Checkout.php(143): resolve('App\\Services\\Bo...')
#24 /shared/httpd/my-app/app/Jobs/ConfirmCheckoutPayments.php(67): App\Models\Checkout->setBookingStatus(6)
#25 [internal function]: App\Jobs\ConfirmCheckoutPayments->handle()
#26 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#27 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#28 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#29 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php(576): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#30 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Container\Container->call(Array)
#31 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(App\Jobs\ConfirmCheckoutPayments))
#32 /shared/httpd/my-app/vendor/hyn/multi-tenant/src/Queue/DispatcherMiddleware.php(36): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\ConfirmCheckoutPayments))
#33 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Hyn\Tenancy\Queue\DispatcherMiddleware->handle(Object(App\Jobs\ConfirmCheckoutPayments), Object(Closure))
#34 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\ConfirmCheckoutPayments))
#35 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#36 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(49): Illuminate\Bus\Dispatcher->dispatchNow(Object(App\Jobs\ConfirmCheckoutPayments), false)
#37 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\DatabaseJob), Array)
#38 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(337): Illuminate\Queue\Jobs\Job->fire()
#39 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(283): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#40 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(236): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#41 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(102): Illuminate\Queue\Worker->runNextJob('database', 'default', Object(Illuminate\Queue\WorkerOptions))
#42 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(86): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default')
#43 [internal function]: Illuminate\Queue\Console\WorkCommand->handle()
#44 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#45 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#46 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#47 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php(576): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#48 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Console/Command.php(183): Illuminate\Container\Container->call(Array)
#49 /shared/httpd/my-app/vendor/symfony/console/Command/Command.php(255): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#50 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Console/Command.php(170): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#51 /shared/httpd/my-app/vendor/symfony/console/Application.php(1001): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#52 /shared/httpd/my-app/vendor/symfony/console/Application.php(271): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#53 /shared/httpd/my-app/vendor/symfony/console/Application.php(147): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#54 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Console/Application.php(90): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#55 /shared/httpd/my-app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(133): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#56 /shared/httpd/my-app/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#57 {main} [] []
Thanks to @fletch3555 on discord I fixed a secondary bug that happened tried to launch the following job SendMailPurchaseCompleted
I was getting again the website id from Environment
instead of using the already existing attribute $this->website_id
$this->checkout->setBookingStatus(Checkout::STATUS_COMPLETE);
$websiteId = app(\Hyn\Tenancy\Environment::class)->website()->id;
SendMailPurchaseCompleted::dispatch(websiteId, $this->checkout);
in
$this->checkout->setBookingStatus(Checkout::STATUS_COMPLETE);
SendMailPurchaseCompleted::dispatch($this->website_id, $this->checkout);
However the system
connection error is still present.
Based on that stacktrace, I'd guess the issue is with that other package. It appears to be using an Eloquent Builder instance instead of a Model class. Either way, we're unable to directly support another package. Take a look through their code and see if you can figure out what's going on.
The package uses an Eloquent Builder that calls for a Model: https://github.com/qcod/laravel-settings/blob/f87ee09837fcc7db2b0961f909d584b56a0f7575/src/Setting/SettingEloquentStorage.php
public function all($fresh = false)
{
if ($fresh) {
return $this->modelQuery()->pluck('val', 'name');
}
return Cache::rememberForever($this->getSettingsCacheKey(), function () {
return $this->modelQuery()->pluck('val', 'name');
});
}
// ...
protected function modelQuery()
{
return $this->getSettingModel()->group($this->settingsGroupName);
}
// ...
protected function getSettingModel()
{
return app('\QCod\Settings\Setting\Setting');
}
and \QCod\Settings\Setting\Setting
extends Model
Ok I found something.
It appears that when the Setting
model has a null
connection defined. When Model->getConnection(null)
is called, it goes through DatabaseManager->connection(null)
and, as you can see from the screenshot, the default db connection from app['config']['database.default']
is assigned.
When I call the settings library from a controller the function getDefaultConnection()
returns tenant
(see screenshot 1)
However when I call the same library from my job getDefaultConnection()
returns system
(see screenshot 2)
Ok, now I understood why it works only when called in a controller and not on my jobs.
I had to force my tenant connection as hinted in the documentation.
So I added this snippet of code in my AppServiceProvider.php
if ($fqdn = optional($env->hostname())->fqdn) {
config(['database.default' => 'tenant']);
}
However app(Environment::class)->hostname()
is null when called on a Job while works while calling it from a tenant controller.
Removing the snippet I get the error both calling the library from a controller or a job
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tenancy.settings' doesn't exist (SQL: select `val`, `name` from `settings` where `group` = default)
So now the question is: why forcing the tenant connection in tenancy.php doesnt work?
'force-tenant-connection-of-models' => [
\QCod\Settings\Setting\Setting::class,
],
I opened a new ticket #913 for that.
I'm still struggling trying to make the tenant connection work both on controllers and jobs.
Considering force-tenant-connection-of-models
doesn't work, I was able to find a hack to make it work at least on jobs.
I just added this line of code at the beginning of my job handle()
function:
app()->resolveProvider(\Hyn\Tenancy\Providers\Tenants\ConnectionProvider::class)->overrideConnectionResolvers();
That's a horrible hack but that's the only way I found to make jobs work until force-tenant-connection-of-models
is fixed (#751)
Description
I have some issues trying to execute a job on my tenants. I'm using
qcod/laravel-app-settings
library to easily implement custom settings for each tenant. However when my job tries to read the settings table from the tenant it seems that the connection is still set tosystem
and the job fails with this error:Any idea on how to fix this?
If it can be of any help, I tried adding inside my job
handle()
all of the documentation suggested functions and 3 of 4 failed to obtain the current tenant website.Information
ConfirmCheckoutPayments.php job
tenancy.php config
webserver.php config
.env file