hoeveel error-levels?
Pagina: « vorige 1 2 3 volgende »
Jij schuift het loggen steeds op. Jij logt de error niet op de plek dat het gebeurd, maar op de plek wanneer iemand hem ooit gaat opvangen (moet je nog afwachten of dat uberhaupt gebeurd). Dat betekend dat de cacher een exception kan gooien en deze nog voordat hij in een catch terecht komt eindigt in een fatal error waardoor je applicatie plat ligt en de rest niet meer wordt uitgevoerd. Resultaat? Je ziet alleen die fatal error en je logs bevatten niet de exception (hij was immers nog niet opgevangen).
Wat wij zeggen is dat je bij het gooien al moet loggen. Het loggen staat los van de exception. Wanneer er nu een fatal error plaatsvind voor het opvangen van de exception zal je wel een exception in je log file aantreffen (de exception hoeft immers niet meer opgevangen te worden om te cachen).
sorry ward...
>> Wat is bijvoorbeeld het verschil tussen een error en critical? En tussen critical en alert? Dat komt toch allemaal op hetzelfde neer?
Ik denk dat je het meer als een hierarchy moet zien. De critical is een algemene level voor problematieke errors. Wat specifieker zijn de alert en emergency (beide zijn kritiek).
Ah, op die manier. Ik geloof dat ik nu begin te begrijpen wat jullie bedoelen. Maar moet ik dan niet loggen op de plek waar ik opvang, of moet ik én én loggen?
Je logt wat er fout gaat waar het fout gaat en je logt dat je een exception opvangt waar je hem opvangt.
Code (php)
Dat lijkt logisch. Bij onvoldoende $FooStuff hebben we een false en een nette exception. Daar kunnen we elders wat mee:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
try {
$foo = new Foo();
$bar = $foo->getFooStuff();
} catch (FooException $e) {
// Auw, een Foo-fout
Logger::warning($e->getMessage);
}
?>
try {
$foo = new Foo();
$bar = $foo->getFooStuff();
} catch (FooException $e) {
// Auw, een Foo-fout
Logger::warning($e->getMessage);
}
?>
Maar dan... treedt er ineens in Foo::initFooStuff() een onverwachte fout op die het script laat crashen of het afbreekt. Je logger komt er dan niet meer aan te pas. Je had eigenlijk al in Foo moeten loggen. Het is immers ook een Foo-fout.
Wat heb je dan nog aan het throwen van exceptions? Ik dacht dat de rauwe PHP errors ook bij het catch() gedeelte van een try-catch block worden opgevangen, en dan automatisch het script stopt.
Harry hogeveen op 25/11/2013 18:37:52:
Er ontstaat dus een fout van PHP (dus geen eigen exception o.i.d) en daardoor stopt het script meteen op die plek, zelfs al voordat je een exception kunt gooien.
Wat heb je dan nog aan het throwen van exceptions? Ik dacht dat de rauwe PHP errors ook bij het catch() gedeelte van een try-catch block worden opgevangen, en dan automatisch het script stopt.
Wat heb je dan nog aan het throwen van exceptions? Ik dacht dat de rauwe PHP errors ook bij het catch() gedeelte van een try-catch block worden opgevangen, en dan automatisch het script stopt.
Zelfs dat kan, door van elke PHP-error een exception te maken. Maar wat niet kan, is een rijtje A -> B -> C -> Logger uitvoeren in de hoop dat alle errors en exceptions van {A,B,C} uiteindelijk als één fout in de Logger belanden.
Class A gaat iets cachen via cacher Class C. Class C gebruikt daar voor Filesystem class F.
Nu lukt het niet om het bestand op te slaan. Class F gooit een exception. Class C vangt 'em op en gooit ook een exception. Class A vangt de exception van class C op. Mijn idee was dan om om de catch van class A de exception van clas C met als previous exception de exception van class F te loggen. Als ik jou goed begrijp zeg jij nu dat je op 3 punten moet loggen, zowel in class F, class C als class A. Correct? Maar dan krijg je wel rare log-berichten:
Code (php)
1
2
3
2
3
25-11-2013 19:26:05 Filesystem: could not save file foo.php
25-11-2013 19:26:05 Cacher: could not cache file foo.php. Filesystem: Could not save file foo.php
25-11-2013 19:26:05 Class A: could not cache foo.php. Cacher: could not cache file foo.php. Filesystem: Could not save file foo.php
25-11-2013 19:26:05 Cacher: could not cache file foo.php. Filesystem: Could not save file foo.php
25-11-2013 19:26:05 Class A: could not cache foo.php. Cacher: could not cache file foo.php. Filesystem: Could not save file foo.php
Is dat niet wat vreemd :-s
@Ward:
Dankjewel voor je voorbeeld. Echter wel een vraag daarover.
>> Maar dan... treedt er ineens in Foo::initFooStuff() een onverwachte fout op die het script laat crashen of het afbreekt.
Oké... maar als dat gebeurt, dan kom je ook niet meer bij de throw terecht, en zal er dus net zo goed niks gelogd worden. Toch?
Ja, dat is inderdaad vreemd. Weet je hoe dat komt? Dat komt doordat jij weer de exceptions logt...
Hihi... LOL :-)))
Weten we in ieder geval waar het aan ligt ;)
Oke, dus als ik je goed begrijp:
1) log je altijd als je een exception gooit
2) log je altijd als je een exception opvangt
Correct?
Bij 2, log je dan alleen WAT er fout gaat "could not cache config"?
Op de manier die jij beschrijft, maak jij dan gebruik van previous errors? Ik dacht dat het idee van de previous errors was dat je de message van een previous error kunt toevoegen aan de huidige message, maar dat zie ik bij nou niet terug??
Maar.. nu lees ik nog even dit
>> Dat komt doordat jij weer de exceptions logt...
Je wil toch de $message loggen? Waarom zou je anders een message meegeven?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php
class Filesystem
{
// ...
public function write($file, $content)
{
if (problem) {
$this->logger->error(__CLASS__.' - could not save file '.$file);
throw new FilesystemException('File cannot be written: '.$the_problem);
}
}
public function read($file)
{
if (!file_exists) {
$this->logger->debug(__CLASS__.' - requested not existing file '.$file);
throw new FilesystemException('File "'.$file.'" does not exists');
}
return file_get_contents($file);
}
}
class RouteCacher extends FileCacher
{
// ...
public function set($routes)
{
try {
$data = serialize($routes);
$this->filesystem->write($this->generateNewFileName(), $data);
} catch (\Exception $e) { // geen FileSystemException, omdat serializen ook exceptions kan opleveren
$this->logger->warning('Could not cache routes ');
throw new CacheWriteException('Routes cannot be cached', 0, $e);
}
}
public function getAll()
{
try {
$data = $this->filesystem->read($this->getFileName());
return deserialize($data);
} catch (FileSystemException $e) {
$this->logger->debug('Could not read cached routes');
throw new CacheReadException('Cached routes cannot be find or loaded', 0, $e);
}
}
}
class Router
{
public function doLoad()
{
try {
$routes = $this->cacher->getAll();
} catch (CacherReadException $e) {
// cacher mislukt, blijkbaar gaat er wat mis of bestaat het cache bestand nog niet
$routes = ...; // load routes
try {
$this->cacher->set($routes);
} catch (CacheWriteException $e) {
$this->logger->notice('Catched exception: '.DebugUtil::stringifyException($e));
}
}
return $routes;
}
}
?>
class Filesystem
{
// ...
public function write($file, $content)
{
if (problem) {
$this->logger->error(__CLASS__.' - could not save file '.$file);
throw new FilesystemException('File cannot be written: '.$the_problem);
}
}
public function read($file)
{
if (!file_exists) {
$this->logger->debug(__CLASS__.' - requested not existing file '.$file);
throw new FilesystemException('File "'.$file.'" does not exists');
}
return file_get_contents($file);
}
}
class RouteCacher extends FileCacher
{
// ...
public function set($routes)
{
try {
$data = serialize($routes);
$this->filesystem->write($this->generateNewFileName(), $data);
} catch (\Exception $e) { // geen FileSystemException, omdat serializen ook exceptions kan opleveren
$this->logger->warning('Could not cache routes ');
throw new CacheWriteException('Routes cannot be cached', 0, $e);
}
}
public function getAll()
{
try {
$data = $this->filesystem->read($this->getFileName());
return deserialize($data);
} catch (FileSystemException $e) {
$this->logger->debug('Could not read cached routes');
throw new CacheReadException('Cached routes cannot be find or loaded', 0, $e);
}
}
}
class Router
{
public function doLoad()
{
try {
$routes = $this->cacher->getAll();
} catch (CacherReadException $e) {
// cacher mislukt, blijkbaar gaat er wat mis of bestaat het cache bestand nog niet
$routes = ...; // load routes
try {
$this->cacher->set($routes);
} catch (CacheWriteException $e) {
$this->logger->notice('Catched exception: '.DebugUtil::stringifyException($e));
}
}
return $routes;
}
}
?>
Ik snap ongeveer wat je doet, alhoewel ik het nog wel vrij lastig vindt. Waarom gebruik je bij sommige methods $this->logger->debug ipv $this->logger->warning? Wat is het verschil?
Hier log je toch alsnog de complete exception?
$this->logger->notice('Catched exception: '.DebugUtil::stringifyException($e));
Ik zie dat je dit doet:
catch (\Exception $e)
Doe je dat normaal ook met die slash ervoor, of gebruik je dan use Exception?
Debug hoeft niet perse een fout te zijn, warning is een echte fout.
>> Hier log je toch alsnog de complete exception?
>>
>> $this->logger->notice('Catched exception: '.DebugUtil::stringifyException($e));
Ja, als ik een exception catch log je hem wel helemaal, je kan er echter niet veel andere informatie toegevoegd.
>> Doe je dat normaal ook met die slash ervoor, of gebruik je dan use Exception?
Voor dingen uit globale namespace gebruik ik altijd de slash ervoor.
Dan krijg je toch weer die dubbele meldingen zoals in mijn voorbeeldje?
>> Voor dingen uit globale namespace gebruik ik altijd de slash ervoor.
Oké. Heb je daar een speciale reden voor?
Mijn code laat gewoon zien hoe mijn log voorbeeldje van 2 reacties terug in de code eruit ziet. Zie jij dubbele meldingen?
>> Heb je daar een speciale reden voor?
't is de algemene standaard voor open source projecten.
Nee, maar je hebt de catched exception melding ook niet voluit geschreven :)
Wat ik bedoel is dat in de catched exception melding die 2 voorgaande meldingen toch terugkomen? Daar zorgt dit toch voor, tenminste.. daar ging ik vanuit?
$this->logger->notice('Catched exception: '.DebugUtil::stringifyException($e));
Toevoeging op 25/11/2013 22:36:33:
>> geen FileSystemException, omdat serializen ook exceptions kan opleveren
Waar haal jij de informatie vandaan dat serialize exceptions kan gooien?
Ozzie PHP op 25/11/2013 21:34:12:
>> geen FileSystemException, omdat serializen ook exceptions kan opleveren
Waar haal jij de informatie vandaan dat serialize exceptions kan gooien?
Waar haal jij de informatie vandaan dat serialize exceptions kan gooien?
http://php.net/manual/en/class.serializable.php
https://github.com/php/php-src/blob/master/Zend/zend_interfaces.c#L458
http://us1.php.net/serialize
Alleen in de github link zie ik staan dat er een exception kan worden gegooid, maar dat gaat volgens mij niet over de php functie serialize?? Als het ook voor de functie geldt, waarom zie ik dat dan niet staan op de php.net pagina?
Een class kan ook een Serializable interface implementeren en dan kun je een exception throwen waarneer je vindt dat er iets uitzonderlijks gebeurd.
Oké, maar de functie serialize zelf (deze dus: http://us1.php.net/serialize) die gooit geen exceptions?
Als je een class die Serializable implementeert in de serialize functie gooit en die class gooit een exception, doet de serialize functie dat dus ook.