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

Exception thrown when Mobile_Detect return null as user agent #42

Open
fratsloos opened this issue Jun 12, 2023 · 0 comments
Open

Exception thrown when Mobile_Detect return null as user agent #42

fratsloos opened this issue Jun 12, 2023 · 0 comments

Comments

@fratsloos
Copy link

In some cases I see the following log in my Laravel logs:

[2023-06-11 03:51:45] live.ERROR: Spinen\BrowserFilter\Support\ParserCreator::parseAgent(): Argument #1 ($agent) must be of type string, null given, called in /path/to/vendor/spinen/laravel-browser-filter/src/Filter.php on line 56 {"url":"https://website.com","method":"GET","exception":"[object] (TypeError(code: 0): Spinen\\BrowserFilter\\Support\\ParserCreator::parseAgent(): Argument #1 ($agent) must be of type string, null given, called in /path/to/vendor/spinen/laravel-browser-filter/src/Filter.php on line 56 at /path/to/vendor/spinen/laravel-browser-filter/src/Support/ParserCreator.php:32)
[stacktrace]
#0 /path/to/vendor/spinen/laravel-browser-filter/src/Filter.php(56): Spinen\\BrowserFilter\\Support\\ParserCreator->parseAgent()
#1 [internal function]: Spinen\\BrowserFilter\\Filter->__construct()
#2 /path/to/vendor/laravel/framework/src/Illuminate/Container/Container.php(954): ReflectionClass->newInstanceArgs()
#3 /path/to/vendor/laravel/framework/src/Illuminate/Container/Container.php(795): Illuminate\\Container\\Container->build()
#4 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(933): Illuminate\\Container\\Container->resolve()
#5 /path/to/vendor/laravel/framework/src/Illuminate/Container/Container.php(731): Illuminate\\Foundation\\Application->resolve()
#6 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(918): Illuminate\\Container\\Container->make()
#7 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(169): Illuminate\\Foundation\\Application->make()
#8 /path/to/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#9 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#10 /path/to/vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(41): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#11 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\AuthenticateSession->handle()
#12 /path/to/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#13 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#14 /path/to/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#15 /path/to/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#16 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle()
#17 /path/to/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#18 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#19 /path/to/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#20 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#21 /path/to/app/Http/Middleware/Auth/ValidateForExtendedSessions.php(24): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#22 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\Auth\\ValidateForExtendedSessions->handle()
#23 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /path/to/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): Illuminate\\Pipeline\\Pipeline->then()
#25 /path/to/vendor/laravel/framework/src/Illuminate/Routing/Router.php(777): Illuminate\\Routing\\Router->runRouteWithinStack()
#26 /path/to/vendor/laravel/framework/src/Illuminate/Routing/Router.php(741): Illuminate\\Routing\\Router->runRoute()
#27 /path/to/vendor/laravel/framework/src/Illuminate/Routing/Router.php(730): Illuminate\\Routing\\Router->dispatchToRoute()
#28 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch()
#29 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#30 /path/to/vendor/livewire/livewire/src/DisableBrowserCache.php(19): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#31 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Livewire\\DisableBrowserCache->handle()
#32 /path/to/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#33 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#34 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#35 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#36 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#37 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#38 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#39 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#40 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#42 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#44 /path/to/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#45 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then()
#46 /path/to/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#47 /path/to/public/index.php(51): Illuminate\\Foundation\\Http\\Kernel->handle()
#48 {main}
"}

It appears that the method getUserAgent of Mobile_Detect returns null, which is correct according to the docbloc of the method, while parseAgent in ParserCreator expects a string. Based on the logs I'm not able to recreate the request which caused it. There is no request logged in the access_log on the same time, but before and after the time of the Laravel log I see some activity from the Bing bot.

As I can't reproduce the request it's kind of hard to find the exact reason why this fails. Therefore I did not create a PR. My suggestion for a fix is to check the user agent first in the constructor of Filter.php and then check it in validateRules:

abstract class Filter
{
    public function __construct(
        protected Cache $cache,
        protected Config $config,
        protected Mobile_Detect $detector,
        protected ParserCreator $parser,
        protected Redirector $redirector
    ) {
        $userAgent = $detector->getUserAgent();
        $this->client = !is_null($userAgent)
            ? $parser->parseAgent($userAgent)
            : null;
    }

    public function validateRules(): void
    {
        if (is_null($this->client) || empty($this->getRules())) {
            return;
        }

        foreach ($this->getRules() as $device => $browsers) {
            $this->validDeviceRule($device, $browsers);
        }
    }
}

But as said, because I can't recreate the request I cannot test this solution.

I'm using version 3.1.0 of this package with PHP 8.2.

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

No branches or pull requests

1 participant