Fixed handleFatalError does not rollback exceptions

Xon

Well-known member
Affected version
2.0.4
The shutdown function handleFatalError, does not rollback exceptions. This can result in a case where a logged exception will result in in the logging being rolled back due to an outstanding transaction.
 
This is can be reproduced by extending login action inside XF:Pub\Login controller.

Extended action would look something like this
PHP:
public function actionLogin()
{
    $response = parent::actionLogin();

    try
    {
        /** @var \Blizzard\DramaLeague\Repository\Hero $heroRepo */
        $heroRepo = $this->repository('Blizzard\DramaLeague:Hero');
        $heroRepo->OWLMoreLikeDramaLeague();
    }
    catch (\Exception $e)
    {
        // do not block login if any sort of error occurs
        \XF::logException($e);
        if ($this->app()->config('debug') === true)
        {
            throw $e;
        }
    }
    return $response;
}

Inside method OWLMoreLikeDramaLeague() calls another method which has looks similar to this:
PHP:
$this->db()->beginTransaction();

if (empty($someUser->Heroes))
{
    $allHeroes = [];
    foreach ($data['heroes'] AS $userId => $hero)
    {
        if (is_array($hero))
        {
            if (!isset($allHeroes[key($hero)]))
            {
                $allHeroes[key($hero)] = [];
            }

            foreach ($hero AS $heroName => $heroValue)
            {
                $allHeroes[key($hero)][] = $heroValue;
            }

            // below line will throw exception Array to string conversion but won't get logged in ACP
            $allHeroes[key($hero)] = array_unique($allHeroes[key($hero)]);
        }
        else
        {
            $allHeroes[] = $hero;
        }
    }

    $this->logHero($someUser, [$someOtherVariable], $allHeroes,);
}

$this->db()->commit();
 
Back
Top Bottom