Eigener Exceptionhandler

Hi,

ich versuche die Fehlermeldungen abzufangen um sie neben dem Log an Externe System (Mail, Chat) zu schicken.
Eckdaten: ce-6.1.5, php 7.3.9

Dazu habe ich ein neues Modul gemacht. in metadata.php habe ich

'extend' => array( 'oxexceptionhandler' => 'kemweb/kwexceptionhandler/kwExceptionHandler' )

und in kwExceptionHandler.php:

class kwExceptionHandler extends kwExceptionHandler_parent
{
    public function writeExceptionToLog($exception)
    {
        parent::writeExceptionToLog($exception);

        $logger = Registry::getLogger();
        $logger->error('kwExceptionHandler!');
    }
}

Modul ist aktiviert und im Backend zeigt er mir, dass der OxidEsales\Eshop\Core\Exception\ExceptionHandler mit kemweb/kwexceptionhandler/kwExceptionHandler erweitert wurde.

Wenn ich jedoch eine Exception werfe wird nur der Core ExceptionHandler aufgrufen.

Versuch 2:
Dann habe ich das set_exception_handler() in source/bootstrap.php gesehen und in source/modules/functions.php meinen Handler eingebunden:

require 'kemweb/kwexceptionhandler/kwExceptionHandler.php';

$debugMode = (bool) \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class)->getVar('iDebug');
set_exception_handler(
    [
        new kwExceptionHandler($debugMode), # extends \OxidEsales\Eshop\Core\Exception\ExceptionHandler
        'handleUncaughtException'
    ]
);
unset($debugMode);

Das wird auch ausgef├╝hrt, aber nach wie vor werden landen die Exceptions nicht dort.

Hat jemand ein Beispiel wie man es richtig macht?

Versuch 1

welche Metaversionsnummer nutzt? 1.0?

Versuch 2

Du musst daran denken die ├ťberladungskette einzuhalten. Aus

new kwExceptionHandler($debugMode), # extends \OxidEsales\Eshop\Core\Exception\ExceptionHandler

m├╝sste

oxNew(\OxidEsales\Eshop\Core\Exception\ExceptionHandler::class, $debugMode),

werden.

Metaversion hab ich auf 1.2 gestellt.

oxNew(\OxidEsales\Eshop\Core\Exception\ExceptionHandler::class, $debugMode),

geht nicht. Da wirft er:

Fatal error: Uncaught Error: Call to undefined function startProfile() in source/oxfunctions.php:99

Und der Stack Trace zeigt auf dieses oxNew().

wie genau erzeugst Du eine Exception? Baust Du einen Syntax Fehler ein oder ├Ąhnliches?

Der ExceptionHandler ist anscheinend auch als deprecated markiert, dort gab es letztens einen Forumseintrag zum Monolog Logging von Symfony Neues OXID-Logging f├╝r Info-Eintr├Ąge nutzen vielleicht hilft Dir dieser Ansatz mehr weiter :slight_smile:

Das liegt aber an der bootstrap.php, weil die function startProfile() nur noch in der overrideablefunctions.php definiert ist und diese wird sp├Ąter eingebunden als die modules/functions.php

Das liegt aber an der bootstrap.php, weil die function startProfile() nur noch in der overrideablefunctions.php definiert ist und diese wird sp├Ąter eingebunden als die modules/functions.php

Ja und da beist sich doch die Katze in den Schwanz. Denn dem Kommentar in der bootstrap.php nach soll der Error Handler genau dort ├╝berschrieben werden:

Set exception handler before including modules/functions.php so it can be overwritten easiliy by shop operators.

Nun habe ich die bootstrap.php ge├Ąndert, aber gef├╝hlt ist das schon sehr nahe an einem core hack und die Datei wird potenziell bei einem Update ├╝berschrieben. Oder sehe ich das falsch?

Damit funktioniert es nun aber, sehr sch├Ân.
Vielen Dank schon mal und frohe Weihnachten! :slight_smile:

Zusammenfassung

Hier nochmal die Zusammenfassung, falls das nochmal jemand machen will:

in der source/bootstrap.php habe ich modules/functions.php unter overridablefunctions.php geschoben:

/**
 * modules/functions.php moved, see below...
 */

/**
 * The functions defined conditionally in this file may have been overwritten in 'modules/functions.php',
 * so their functionality may have changed completely.
 */
require_once OX_BASE_PATH . 'overridablefunctions.php';

/**
 * Custom bootstrap functionality.
 * Moved below overridablefunctions to use oxNew()
 */
if (@is_readable(OX_BASE_PATH . 'modules/functions.php')) {
    include OX_BASE_PATH . 'modules/functions.php';
}

Dann habe ich in modules/functions.php meinen ErrorHandler hinzugef├╝gt:

$debugMode = (bool) \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class)->getVar('iDebug');
set_exception_handler(
    [
        oxNew(\OxidEsales\Eshop\Core\Exception\ExceptionHandler::class, $debugMode),
        'handleUncaughtException'
    ]
);
unset($debugMode);

Mein ErrorHandler ist wie oben beschrieben als eigenes Module hinzugef├╝gt.

1 Like

Nein, siehst Du richtig.

Idee um eine updatesichere L├Âsung zu implementieren w├Ąre das require_once der overrideabelfunctions.php in Deine functions.php oben setzen. Vorteil w├Ąre die bootstrap.php bleibt unver├Ąndert und das require_once stellt sicher das nur 1x included.

Jaaa! Prima. So gef├Ąllt mir das.

Also einfach in modules/functions.php die overridablefunctions laden und dann den ErrorHandler ├╝berschreibbar machen. Dann geht es mit dem eigenen Module wie oben beschrieben:

require_once OX_BASE_PATH . 'overridablefunctions.php';

$debugMode = (bool) \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class)->getVar('iDebug');
set_exception_handler(
    [
        oxNew(\OxidEsales\Eshop\Core\Exception\ExceptionHandler::class, $debugMode),
        'handleUncaughtException'
    ]
);
unset($debugMode);
1 Like

Gerne, Dir auch frohe Feiertage und einen guten Rutsch! :slight_smile: