Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> errorHandler
e-Gandalf
post 11.07.2003, 17:46:46
Post #1





Grupa: Przyjaciele php.pl
Postów: 195
Pomógł: 0
Dołączył: 7.07.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Witam.
Jak mozna wyczytac z tytulu zastanawiam sie nad optymalnym rozwiazaniem oblugi bledow w CMSie. (mowa o php 4 - no exceptions)

Obsluga bledow sklada sie z dwoch podelementow:

1) Obsluga bledow skladni - zglaszanych przez silnik php i przechwytywanych przez error_handler

2) Obsluga bledow logicznych i algorytmicznych, niewykrywalnych dla php. Zglaszanych z poziomu kodu.

Martwia mnie obydwa problemu, ale z roznych wzgledow. Pierwszy, dlatego, ze php zglasza szalenie mala ilosc informacji o bledzie (np. nie ma mozliwosci uzyskania inforamcji o linii w ktorej nastapil blad!!!).
Drugi, z powodu (tak podejrzewam) malego doswiadcznia z tematem.

Na poczatku nie wiedzialem wogule jak podejsc do tematu i lazilem wokol niego jak pies wokol jeza. W koncu sprecyzowalem zalozenia obslugi bledow. Musi obslugiwac jak najwiekszy zakres bledow, kontrolowac stabilnosc aplikacji, obslugiwac "tranzakcje" (*1) oraz w jak najlatwiejszy sposob integrowac sie z CMSem (*2).

*1) chodzi o system podobny do uzywanego w bazach danych. Jesli kawalek kodu ma wykonac logiczna operacje "dodania konta" ktora sklada sie z dodania wpisu do tablicy |accounts|, dodania wpisu do tablicy |account_privs| oraz dodania dwoch katalogow (zalozmy!!) to fajnie by bylo, moc to latwo wycofac jest cokolwiek pojdzie nie tak.

*2) Innymi slowy, aby latwo i czysto wygladalo w CMSie wybor czy wyswietlac dalej skrypt czy juz komunikat o bledzie.

Wstepnie zaprojektowalem cos w tym stylu:

[php:1:f44bd586cd]<?php
<?php
/**************************************************
*
* Error Class. Handling errors
*
***************************************************
*
* No table related.
*
***************************************************
*
* Detail description
* @author Zbigniew Braniecki (gandalf@przeglad.com.pl)
* @version 1.0 M1
* @copyright Zbigniew Braniecki
* @access private
* @relase_date 08.10.2002
*
***************************************************
*
* Short Description
*
* Variables:
* errorlevel - Describes status of system.
* Possible codes are:
* 0 - no error
* 1 - notice error - something might be wrong, but it miht be ok too
* 2 - warning error - something is wrong, but script works
* 3 - rollback error - error in setting data. should be rolled back and warned
* 4 - security error - there was a try of illegal access
* 5 - fatal error - module wont work.
* 6 - gcms error - gcms wont run
*
* errors - Array of errors code with modules name and description.
* "code" - Code number
* "trasaction" - which transaction was active?
* "module" - Module name
* "action" - Action
* "description" - Description
*
* Methods:
*
* SetErrorLevel($level,$force=false)
* $force - if set (boolean) New errorlevel is forced even if the old one was higher.
*
* AddError($lvl,$module,$desc)
* Adds error to array of errors
*
* AddToErrFile($module,$desc,$rubbish)
* $rubbish - if there can by any parts (sql rows or files) to clean up, write them down here.
* Adds error to error file.
*
* RunCapture()
* System captures php errors and log them.
*
***************************************************
*
* Known bugs and problems
*
***************************************************
*
* Notes
*
***************************************************/
class ErrorClass {
var $errorlevel = 0;
var $errors = Array('cms'=>Array(), 'code'=>Array());
var $debug_mode = true;
var $security = false;
var $php_errcode = Array(1=>6, 2=>5, 4=>6, 8=>1, 16=>6, 32=>5, 64=>6, 128=>5, 256=>5, 512=>5, 1024=>1, 2056=>-1);

var $transactions = Array();

function SetErrorlevel ($level, $force=false) {
if (($level>$this->errorlevel) || $force) {
$this->errorlevel = $level;
}
return true;
}

function CreateTransaction ($name) {
$this->transactions[] = Array('name' => $name, 'rollback' => Array(), 'errors'=> false);
return key($this->transactions);
}

function FinishTransaction ($id) {
unset($this->transactions[$id]);
return true;
}

function Rollback ($tr_id, $module, $method, $argList) {
$this->transactions[$tr_id]['rollback'][] = Array('module'=>$module, 'method'=>$method, 'arglist'=>$argList);
return true;
}

function AddError ($lvl, $module, $action, $desc, $tr_id=false, $type='cms') {
$GLOBALS['system']->reload = false;
$this->SetErrorlevel($lvl);
switch ($lvl) {
case 0:
$code=$GLOBALS['sysdict']['error_no_error'];
break;
case 1:
$code=$GLOBALS['sysdict']['error_notice'];
break;
case 2:
$code=$GLOBALS['sysdict']['error_warning'];
break;
case 3:
$code=$GLOBALS['sysdict']['error_rollback'];
break;
case 4:
$code=$GLOBALS['sysdict']['error_security'];
break;
case 5:
$code=$GLOBALS['sysdict']['error_major'];
break;
case 6:
$code=$GLOBALS['sysdict']['error_blow'];
break;
default:
$code=$GLOBALS['sysdict']['error_unknown'];
}

if ($tr_id === false) {
if (isset($this->transactions[key($this->transactions)])) {
$tr_name = $this->transactions[key($this->transactions)]['name'];
$this->transactions[key($this->transactions)]['errors'] = true;
$tr_id = key($this->transactions);
} else {
$tr_name = '--';
}
}elseif ($tr_id !== '--') {
if (isset($this->transactions[$tr_id])) {
$tr_name = $this->transactions[$tr_id]['name'];
$this->transactions[$tr_id]['errors'] = true;
}else{
$tr_name = '--';
}
}
$this->errors[$type][] = Array('code'=>$code, 'transaction' => $tr_name,'module'=>$module, 'action'=>$action, 'description'=>$desc);
$this->AddToErrFile ($code, $module, $action, $desc);
foreach ($this->transactions as $t) {
foreach ($t['rollback'] as $e) {
eval('$GLOBALS["'.$e['module'].'"]->'.$e['method'].'('.implode($e['arglist'], ',').');');
}
}
if ($type=='code') {
print('<br>'.$GLOBALS['sysdict']['error_code'].': ');
print_r(current($this->errors[$type]));
die($GLOBALS['sysdict']['stop']);
}
return true;
}

function AddToErrFile ($lvl, $module, $action, $desc) {
$fh=fopen('../admin/error.log','a');
fputs($fh,date('[d-m-Y H:i]').' '.$GLOBALS['sysdict']['error'].' ('.$lvl.') '.$GLOBALS['sysdict']['in_module'].' - '.$module.' '.$GLOBALS['sysdict']['in_action'].' - '.$action.' - '.$desc."n");
fclose($fh);
}

function RunCapture(){
function ErrorHandler ($errno, $errstr, $errfile, $errline, $errcontexa) {
global $error;
$error->SetErrorlevel($error->php_errcode[$errno]);
$error->AddError($error->php_errcode[$errno], ' - ', ' - ', $GLOBALS['sysdict']['in_file'].' '.$errfile.', '.$GLOBALS['sysdict']['in_line'].' '.$errline, false, $GLOBALS['sysdict']['code']);
}
set_error_handler('ErrorHandler');
return true;
}

// DONE - 08.10.2002
///////////////////////////////////////////////////////
}
?>
?>[/php:1:f44bd586cd]

(sysdict to slownik CMSa)


uzycie:

[php:1:f44bd586cd]<?php

$tr_id = $errors->CreateTransaction('Adding Account');
if (!mysql_query($q_tmp)) {
$errors->AddError(3, 'Account', 'Adding Account', 'Account was not added due too Mysql Error nr. '.mysql_errno().' - '.mysql_error(), $tr_id);
return false;
}
$curr_id = mysql_insert_id();
$errors->Rollback($tr_id, 'account', 'Remove', Array($curr_id)); // For both
if (!$access->SetPrivileges($curr_id)) {
$errors->AddError(3, 'Account', 'Adding Account', 'Setting Privilages failed', $tr_id);
return false;
}
$errors->FinishTransaction($tr_id);
?>[/php:1:f44bd586cd]

Czyli na ludzki:

1) Rozpocznij tranzakcje
2) Dodaj konto do bazy - jesli sie nie powiedzie zwroc blad (tranzakcja zostanie zatrzymana, ale nie cofnieta - brak Rollbacka)
3) Dodaj rollback
4) dodac uprawnienia - jesli padnie tranzakcja zostanie cofnieta i rollback uruchomiony
.
. tutaj mozna dodawac kolejne elementy
.
n) Zakoncz tranzakcje.


Moj problem jest prosty. Chcialbym Was prosic o pomoc w udoskonaleniu tego, oczyszczeniu... bo napisalem to pewien czas temu i do dzis nie mam pomyslu jak to usprawnic. Mam ogromna nadzieje, ze swierze spojrzenie na problem waszych oczu popchnie cala sprawe do przodu. smile.gif
Bede wdzieczny za kazda sugestie smile.gif

P.S. Zastanawialem sie czy to nie do Oceny, ale zamiast oceny wolalbym teoretyczna chocby dyskusje o samych zalozeniach takiego errorHandlera... moze ja wogule w zla strone ide?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 9)
e-Gandalf
post 14.07.2003, 23:23:49
Post #2





Grupa: Przyjaciele php.pl
Postów: 195
Pomógł: 0
Dołączył: 7.07.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Co poradzic jak jeszcze dobrego nie znalazlem? (dobrego - w zaden sposob nie ingerujacego w wyglad strony, a jedynie udostepniajacego mi bogate API do standardowych elementow obslugi strony. Szybkie, stabilne itp...)

Nie moglem zajrzec do linkow, ktore podales. A z mila checia bym zajrzal smile.gif Odmowilo mi dostepu. Gdzie moge zobaczyc? smile.gif

Co rozumiesz przez debugowanie?
Go to the top of the page
+Quote Post
e-Gandalf
post 16.07.2003, 18:45:58
Post #3





Grupa: Przyjaciele php.pl
Postów: 195
Pomógł: 0
Dołączył: 7.07.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Swietnie. Faktycznie, jestes boski. Bardzo podobaja mi sie algorytmy ktore zastosowales, ciesze sie ze moge z Toba porozmawiac o technologiach, podobaja mi sie Twoje rozwiazania.

Jesli kiedys spytasz o cokolwiek na tym forum postaram Ci sie pokazac kod html wynikowy u mnie...

Co do drugiej czesci - no coz, zeby debugowac jawnie jezyk przydalby sie drugi poziom - praca z debugowaniem php z poziomu php jest raczej pomyslem jalowym (zapraszam do watku "wlasny jezyk"). Tak trafiles na FORUM php. Jesli rozmawiamy o technologiach, to prezentowanie kodu wynikowego oraz stringa jaki wywala w zaden sposob nie miesci sie w jego granicach.
Go to the top of the page
+Quote Post
cagrET
post 17.07.2003, 11:31:06
Post #4





Grupa: Zarejestrowani
Postów: 90
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Opole

Ostrzeżenie: (0%)
-----


czlowieku o czym ty mowisz ?
www.google.com - skrypty do ktorych podalem linki sa open source, wystarczylo poszukac, nazwe znales

chcesz zeby ci wszystko na tacy podac ?


--------------------
code.gosu.pl
Go to the top of the page
+Quote Post
kwiateek
post 17.07.2003, 12:20:21
Post #5





Grupa: Zarejestrowani
Postów: 223
Pomógł: 0
Dołączył: 13.01.2003
Skąd: 3rd ball of mud behind a big ball of burning gas

Ostrzeżenie: (0%)
-----


Cytat
Martwia mnie obydwa problemu, ale z roznych wzgledow. Pierwszy, dlatego, ze php zglasza szalenie mala ilosc informacji o bledzie (np. nie ma mozliwosci uzyskania inforamcji o linii w ktorej nastapil blad!!!).

Hmm, a o __FILE__ i __LINE__ to sie nie slyszalo... ?


--------------------
It's Time to Join the PLD Linux Generation!
<? while (!$success) { $try++; } ?>
Go to the top of the page
+Quote Post
e-Gandalf
post 17.07.2003, 18:34:22
Post #6





Grupa: Przyjaciele php.pl
Postów: 195
Pomógł: 0
Dołączył: 7.07.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat
czlowieku o czym ty mowisz ?
www.google.com - skrypty do ktorych podalem linki sa open source, wystarczylo poszukac, nazwe znales


Geez... masz racje smile.gif

Nawet nie sprawdzilem w googlach. Uznalem, ze to _musi_ byc Twoja autorska technologia, tylko niewiedziec czemu podajesz mi jedynie wynik jej pracy ;p

Cytat
chcesz zeby ci wszystko na tacy podac ?


Nie, chce porozmawiac o metodach obslugi bledow!!!
Go to the top of the page
+Quote Post
e-Gandalf
post 17.07.2003, 18:40:14
Post #7





Grupa: Przyjaciele php.pl
Postów: 195
Pomógł: 0
Dołączył: 7.07.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat
Hmm, a o __FILE__ i __LINE__ to sie nie slyszalo... ?


Problem polega na tym, ze jesli powiedzmy ustawie:

[php:1:f65ebe530a]<?php
function ErrorHandler ($errno, $errstr, $errfile, $errline, $errcontexa) {
global $error;
print(__LINE__);
$error->SetErrorlevel($error->php_errcode[$errno]);
$error->AddError(...);
}
set_error_handler('ErrorHandler');
?>[/php:1:f65ebe530a]

to __LINE__ zwroci mi linie w ktorej poszedl print. A nie linie w ktorej powstal blad.

Ale znalazlem *^^*. $errline zwraca linie.
Go to the top of the page
+Quote Post
cagrET
post 18.07.2003, 22:01:24
Post #8





Grupa: Zarejestrowani
Postów: 90
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Opole

Ostrzeżenie: (0%)
-----


polecam debug_backtrace()


--------------------
code.gosu.pl
Go to the top of the page
+Quote Post
bulek
post 24.10.2003, 12:13:25
Post #9





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 23.10.2003

Ostrzeżenie: (0%)
-----


Poniewaz sam zastanawialem sie nad przechwytywaniem bledow w CMSie kiedys przyszla mi do glowy mysl ktora potem zreszta gdzies wyczytalem - czyli nie jest to tylko moja chora wyobraznia smile.gif. Do obslugi bledy mozna zastosowac ... curl'a. Ogolnie robi sie to poprzez stworzenie z curla proxy.
Zapytanie idzie do proxy ten za pomoca curla pobiera dana strone jesli zobaczy jakis blad /apach lub regexpy sprawdzajace co jest na outpucie/ odsyla na odpowiednia strone.
Mozna tez wplesc curla do srodka aplikacji i zaprzac go do obslugi konkretnych modulow. To jest fajne bo mozemy wtedy dosc latwo przeniesc
czesc aplikacji na inny serwer z mala zmiana w configuracji.
Moze to troszke pojechane ale powninno dzialac smile.gif
Go to the top of the page
+Quote Post
dooshek
post 24.10.2003, 12:44:03
Post #10





Grupa: Zarejestrowani
Postów: 70
Pomógł: 0
Dołączył: 22.10.2003
Skąd: Trójmiasto

Ostrzeżenie: (0%)
-----


Cytat
polecam debug_backtrace()

A ja polecam bardzo fajny modul do php Xdebug. To cudo po wywolaniu bledu pokazuje stos wywołań - działa podobnie jak debug_backtrace ale działa przy każdym błędzie. Używam tego juz od 2 miesięcy i żyć bez tego ciężko - debugowanie jest dosyć proste teraz bo widać co się "po drodze" działo.

http://www.xdebug.org/

Aha, rozszerzenie dziala pod winda i unixowymi - natomiast ma problemy z dzialaniem z roznymi innymi rozszerzeniami (np. z Turck MMCache sad.gif )


--------------------
"Use the force - read the source"
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 18:19