Wyjątki są zaimplementowane w wielu językach programowania np.
http://pl.wikibooks.org/wiki/C++/Obs%C5%82uga_wyj%C4%85tk%C3%B3w
http://msdn.microsoft.com/en-us/library/6dekhbbc(v=vs.80).aspx
http://php.net/manual/en/language.exceptions.php
http://pl.wikipedia.org/wiki/Wyj%C4%85tek
Wyjątek (ang. exception) jest mechanizmem przepływu sterowania używanym w mikroprocesorach oraz współczesnych językach programowania do obsługi zdarzeń wyjątkowych, a w szczególności błędów, których wystąpienie zmienia prawidłowy przebieg wykonywania programu. W momencie zajścia niespodziewanego zdarzenia generowany jest wyjątek, który musi zostać obsłużony poprzez zapamiętanie bieżącego stanu programu i przejście do procedury jego obsługi. W niektórych sytuacjach po obsłużeniu wyjątku można powrócić do wykonywania przerwanego kodu, korzystając z zapamiętanych informacji stanu. Przykładowo obsługa błędu braku strony pamięci polega najczęściej na pobraniu brakującej strony z pliku wymiany, co umożliwia kontynuowanie pracy programu, natomiast błąd dzielenia przez zero powoduje, że wykonywanie dalszych obliczeń nie ma sensu i musi zostać przerwane na trwałe.
Implementacja w pawn ma pewne ograniczenia ( stąd pseudo 😉 ) wynikające z sposobu jakie są one zaimplementowane.
Nie ma np. wyłapywania nie obsłużonych wyjątków wynika to z tego że implementacja takiego mechanizmu wymagała by użycia np. tasków a takie rozwiązanie było by bardzo podatne na błędy i samo w sobie potrafiło by generować sytuacje wyjątkowe ;).
Radził bym to traktować jaką pewnego rodzaju ciekawostkę ale nic nie stoi na przeszkodzie w używaniu tego w pluginach jednak lepiej przyswoić sobie wiedzę o wyjątkach z źródeł podanych na początku.
Download pliku inc na dole wpisu
Przykłady użycia :
Test1
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
}
catch("TestExcept"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
Test2: można zagnieżdżać wyjątki
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
}
catch("TestExcept"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
try(){
testFunction2();
}
catch("TestExcept2"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
}
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
public testFunction2(){
raise("TestExcept2","Test Message2");
}
Test3: można łapać kilka wyjątkow na raz
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
testFunction2();
}
catch("TestExcept TestExcept2"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
public testFunction2(){
raise("TestExcept2","Test Message2");
}
i tutaj wychodzi pierwsze ograniczenie jeśli obie funkcje zgłoszą wyjątki to zostanie obsłużony tylko drugi czyli TestExcept2 , TestExcept zostanie w pamięci więc jeśli mamy taką sytuację powinniśmy wyczyścić pamieć z tych wyjątków w taki sposób.
poprawna implementacja
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
testFunction2();
}
catch("TestExcept TestExcept2"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
clearExcepts( "TestExcept TestExcept2" );
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
public testFunction2(){
raise("TestExcept2","Test Message2");
}
lub
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
testFunction2();
}
catch("TestExcept TestExcept2"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
clearExcept( "TestExcept" );
clearExcept( "TestExcept2" );
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
public testFunction2(){
raise("TestExcept2","Test Message2");
}
jeżeli dwie funkcje zgłaszają ten sam wyjątek też warto to dodać 😉
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
testFunction2();
}
catch("TestExcept"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
clearExcept( "TestExcept" );
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
public testFunction2(){
raise("TestExcept","Test Message");
}
Kolejne ograniczenie to wywoływanie funkcji catch teoretycznie jeśli funkcja zgłosi wyjątek program powinien przejść od razu do bloku catch jednak nie tutaj. W naszym przypadku catch zostanie uruchomione dopiero gdy wszystkie funkcje w bloku try zostaną wykonane.
Przykład
#include
#include
#include
#define PLUGIN "New Plugin"
#define AUTHOR "DarkGL"
#define VERSION "1.0"
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
try(){
testFunction();
testFunction2();
}
catch("TestExcept"){
new szName[ 256 ],
szMessage[ 256 ];
getExceptName( szName , charsmax( szName ) );
getExceptMessage( szMessage, charsmax( szMessage ) );
log_amx( "Print Except '%s' : %s" , szName , szMessage );
clearExcept( "TestExcept" );
}
}
public testFunction(){
raise("TestExcept","Test Message");
}
public testFunction2(){
//pass
}
funkcja testFunction() zgłosi wyjątek mimo to testFuncion2() się wykona dopiero wtedy catch złapie wyjątek
Download
exceptions.inc Download