Mad Exception bileşenini kullananlar...

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
baloglurecep
Üye
Mesajlar: 261
Kayıt: 21 Tem 2006 04:59
İletişim:

Mad Exception bileşenini kullananlar...

Mesaj gönderen baloglurecep »

Arkadaşlar herseke saygılar, hayırlı cumalar diliyorum. Projemde, zamanı belli olmayan, bazen veren bazen vermeyen hatanın sebebini bulamadım. Yaptığım araştırmalar sonucu bir arkadaşım mad exception isminde bir bileşenden bahsetti. Hata yakalamaya yarıyormuş. Bu konuda blgisi olan var mı? Kullanan arkadaşlardan yorumlar bekliyorum. Bunun dışında böyle standart olmayan hataları yakalamak için ne yapılabilinir?

Saygıyla kalınız.
carsoft
Üye
Mesajlar: 138
Kayıt: 01 Ağu 2014 12:27

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen carsoft »

Ben kullanıyorum ücretli bir komponent ....
Mad exception ise yazılımınızda bulunan hataları bulmanıza yardımcı olmak için hazırlanmıştır.mesela programınızda donma , veya hazen oluşan hatalar
gibi bir durum olduğunda mad expect otomatik olarak onu yakalayarak size hata raporu vererek çözmenize yardımcı olur.

site adresi : http://madshi.net
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen xozcanx »

Hocam şahsi fikrim Kodları Try Except Bloğu arasına almaktan yana. Hata oluştuğunda Bir Txt dosyasına hata verdiği Try Except Bloğunun yerini yada hangisi olduğunu yazdırın.

Kendi Kullandığım bir yöntemi sizinle paylaşayım belki işinizi görür.

Kod: Tümünü seç

procedure HataMesaji( E:Exception; mesaj:string);
Begin
  Application.MessageBox(PWideChar(mesaj+#10#10+
                         'Hata Tipi : '+PChar(E.ClassType)+#10#10+
                         'Hata Türü : '+PChar(E.ClassName)+#10#10+
                         'Hata Kodu : '+PChar(E.Message)),'HATA!',MB_OK+
                         MB_ICONASTERISK);
// Bu kısımda hatayı txt dosyasına da kaydedebilirisiniz.                         
End;
Kullanımı için;

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var ituru:integer;
begin
  Try
    .
    .
    .
  Except on E:Exception do
    HataMesaji(E,'Buton1 Üzerinde Hata Oluştu!');
  End;

end;
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen thelvaci »

xozcanx yazdı:Hocam şahsi fikrim Kodları Try Except Bloğu arasına almaktan yana. Hata oluştuğunda Bir Txt dosyasına hata verdiği Try Except Bloğunun yerini yada hangisi olduğunu yazdırın.

Kendi Kullandığım bir yöntemi sizinle paylaşayım belki işinizi görür.

Kod: Tümünü seç

procedure HataMesaji( E:Exception; mesaj:string);
Begin
  Application.MessageBox(PWideChar(mesaj+#10#10+
                         'Hata Tipi : '+PChar(E.ClassType)+#10#10+
                         'Hata Türü : '+PChar(E.ClassName)+#10#10+
                         'Hata Kodu : '+PChar(E.Message)),'HATA!',MB_OK+
                         MB_ICONASTERISK);
// Bu kısımda hatayı txt dosyasına da kaydedebilirisiniz.                         
End;
Kullanımı için;

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var ituru:integer;
begin
  Try
    .
    .
    .
  Except on E:Exception do
    HataMesaji(E,'Buton1 Üzerinde Hata Oluştu!');
  End;

end;
Nazicane tavsiyem asla try..except blokları içinde hatayı bertaraf etmemeniz yönünde olacak. Örneğinizde hata oluşması durumunda bir mesaj diyaloğu çıkartıyorsunuz ekrana belki de ardından hatayı da logluyorsunuz ama; hatayı re-raise etmediğiniz için kodunuz try..except bloğundan sonraki satırdan itibaren devam ediyor. Bu beklemediğiniz sorunlara neden olabilir. Hata loglamak yada özelleştirmek istiyorsanız TApplication.OnException ile merkezi bir yönetim sergileyebilirsiniz ve hata ile işiniz bittiğinde(loglama gibi) hatayı yeniden re-raise etmeyi unutmayın.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen mrmarman »

Tuğrul bey'e katılarak Try Except bloklarını kullanım alanı olarak sadece program akışına tam hükmettiğiniz durumlarda başvurun.

Vaktim varken size bu tam hakimiyeti basit bir anekdot ile örnekleyeyim, bir Zoolog, bir Matematikçi ve bir Bilgisayar programcısı Afrika kıtasında bir FİL arıyor olsun. -Kısa keseyim- Her üçü de Afrika Kıtasının en aşağısından Ümit burnundan başlayıp tarayarak yukarıda Cebeli Tarık boğazına kadar gelir. Zoolog türlerden yürür, Matetikçi ispat ile yürür, bulamazlarsa işi bırakırlar sıkıntı olmaz. Ancak Bilgisayar Programcısı Cebeli Tarık boğazına önceden en az (1) tane FİL temin ederek bırakır ki sonra hiç fil bulamazsa aman Exception'a düşmesin. :wink:

Örneğin kullanıcı veri girişi durumlarında, sayısal giriş yerine karakter girişlerini sınırlayarak hataya mahal bırakmamak, hataya mahal bırakıp Try Except kurmaktan daha verimli ve kullanıcı dostudur.

Özetle, olası istisnayı kendimiz dizginlemek istersek Try / Except kullanırız. Kaynağı belirsiz hata ihtimalinde karşı değil. Hatanın olabileceği durumlarda ne yapacağımızı bilmemiz lazım. Yokmuş gibi gözümüzü kapatmak olmaz. Bunun altını çizmek istedim.
Resim
Resim ....Resim
baloglurecep
Üye
Mesajlar: 261
Kayıt: 21 Tem 2006 04:59
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen baloglurecep »

Cevap veren tüm arkadaşlara teşekkür eder saygılarımı sunarım. Kod bloğumu try-except blokları arasına almadım. Program akışı stabil çalışıyor iken bazen zamanı belli olmayan bir yerde hata vermesi ve çalışmayı durdurması. Bazen de hiç hata vermiyor. Timer nesnesine bağlı çalışıyor. Hata stabil olsa belli zaman sonra ya da belli bir işlem arkasından vermesi gerek. Böyle bir durum yok. mrmarman hocamın dediği gibi hata alabileceğim ya da hata oluşabilecek bir kısım olmadığından kullanmadım.

crsoft arkadaşım kompanet işe yarıyor mu? faydasını gördünüz mü? alınmaya değer mi? delphi 7 sürümü var mı?

Saygıyla kalınız.
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen xozcanx »

thelvaci yazdı:
Nazicane tavsiyem asla try..except blokları içinde hatayı bertaraf etmemeniz yönünde olacak. Örneğinizde hata oluşması durumunda bir mesaj diyaloğu çıkartıyorsunuz ekrana belki de ardından hatayı da logluyorsunuz ama; hatayı re-raise etmediğiniz için kodunuz try..except bloğundan sonraki satırdan itibaren devam ediyor. Bu beklemediğiniz sorunlara neden olabilir. Hata loglamak yada özelleştirmek istiyorsanız TApplication.OnException ile merkezi bir yönetim sergileyebilirsiniz ve hata ile işiniz bittiğinde(loglama gibi) hatayı yeniden re-raise etmeyi unutmayın.
Hocam Merhaba;
Sizin ve Muharrem hocamızın yazılarını dikkatlice okudum. Doğru bildiğim yanlışlarımı düzeltmek adına re-raise için hemen bir araştırma yaptım ve karşıma Buradaki örnek çıktı. Umarım dediğinizi doğru anlamışımdır varsa yanlışım düzeltirseniz memnun olurum. Sizinde söylediğiniz gibi Try Except bloğundan sonraki kodlar işlemiyor. fakat benim verdiğim örnekte devam ediyor.
basit düşünüldüğünde çok haklısınız Try Except bloğunda aldığımız sonuca göre blok sonrasında işlem devam eder de kayıtlar vs. yapılırsa dediğiniz gibi ciddi sorunlar çıkacaktır. :!: TApplication.OnException için Buradaki örnekte olduğu gibi bir yapıdan mı bahsettiniz kusura bakmayın yardımcı olayım derken kendim yardım arar oldum :|
Teşekkürler.
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen thelvaci »

Merhaba, evet muharrem bey; tüm iyi niyeti ile arkadaşlarımıza yardımcı olmaya gayret ediyor, sağolsun. Re-raise hususunda verdiğiniz örnek doğru bir örnek. Lâkin at address demenize gerek yok. Örneğin şu şekilde kullanabilirsiniz:

Kod: Tümünü seç

var
	Sonuc : Double;
	Sayi	: Double;
	
	try
		Sayi := 0;
		Sonuc := 15 / Sayi;	
	except on E: Exception do
		ShowMessage(E.Message + ' hatası oluştu');	 // Division by zero 
		Log(E);
		
		raise; // re-raise dediğim bu kısım
	end;
	
	ShowMessage('Hata oluşur ise akış bu noktaya kadar gelemez.!');
Application.OnException hususunda da verdiğiniz linkteki örneği deneyip sonucu gözlemleyebilirsiniz. Uygulama içindeki tüm hataların ilgili kod bloğuna yönlenmesini garanti altına almış olursunuz. Bu sayede uygulamadaki hata'ları istediğiniz gibi loglayabilirsiniz gerekiyor ise.
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen esistem »

Selam,
yeri gelmişken bende @mrmarman ve @thelvaci hocalarıma bir danışayım istedim. Aşağıdaki fonksiyonu sürekli olarak yıllardır kullanıyorum, herhangi bir sorunla karşılaşmadım şimdiye kadar fakat "raise" olayına kafam takıldı? kodun sonuna eklemem gereklimi? gerekli ise nedendir, cevap verebilirseniz memnun olurum.

Kod: Tümünü seç

function ProcEkleCommit(DBase:TIBDatabase; TransName:TIBTransaction; StoredName:String; Query:TIBQuery; Values: Array Of Variant; Out ckod:integer):Boolean;
 var
   Stored : TIBStoredProc;
   X : Integer;
begin
 TRY
  Stored:=TIBStoredProc.Create(Application.MainForm);
   with Stored do
   begin
                  Database       := DBase;
                  Transaction    := TransName;
                  StoredProcName := StoredName;
                  Prepare;
                  For x := 0 to Length(Values) - 1 Do Params[x+1].Value := Values[X];
                  ExecProc;
                  UnPrepare;
   end;
    TransName.CommitRetaining;
    ckod := Stored.Params[0].AsInteger;
                    (Query AS TIBQuery).Close;
                    (Query AS TIBQuery).Open;
                                     (Query AS TIBQuery).Locate('KOD',INTTOSTR(ckod),[]);
                    Result:=True;
 Stored.Free;
 EXCEPT
 on E: Exception do begin
 TransName.RollbackRetaining;
 Result:=False;
 MessageDlg('DİKKAT...!'+#13+StoredName+' - SP (CommitEkle) Hatası Oluştu'+#13+'Hata Tekrarlarsa, Lütfen www.xxx.com ile iletişime geçiniz.'+#13+E.ClassName + #13 + E.Message, mtInformation, [mbOK], 0);
//loglavegonder(firmaadi);
                        end;
 END;
end;
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen xozcanx »

thelvaci yazdı:Merhaba, evet muharrem bey; tüm iyi niyeti ile arkadaşlarımıza yardımcı olmaya gayret ediyor, sağolsun. Re-raise hususunda verdiğiniz örnek doğru bir örnek. Lâkin at address demenize gerek yok. Örneğin şu şekilde kullanabilirsiniz:

Kod: Tümünü seç

var
	Sonuc : Double;
	Sayi	: Double;
	
	try
		Sayi := 0;
		Sonuc := 15 / Sayi;	
	except on E: Exception do
		ShowMessage(E.Message + ' hatası oluştu');	 // Division by zero 
		Log(E);
		
		raise; // re-raise dediğim bu kısım
	end;
	
	ShowMessage('Hata oluşur ise akış bu noktaya kadar gelemez.!');
Application.OnException hususunda da verdiğiniz linkteki örneği deneyip sonucu gözlemleyebilirsiniz. Uygulama içindeki tüm hataların ilgili kod bloğuna yönlenmesini garanti altına almış olursunuz. Bu sayede uygulamadaki hata'ları istediğiniz gibi loglayabilirsiniz gerekiyor ise.
Tuğrul Hocam ALLAH sizden razı olsun.Çok önemli bir bilgiyi öğrettiniz. Malesef Function lar Procedure ler içinde Try Except e başvuruyorum Genellikle SQL tanımlamalarında yapıyorum ki Tespiti kolay olsun.


Esistem Hocam şöyle düşünün Try Except ile hata aldığınızda Try Except ten sonraki kodların çalışmasını önlemek istiyoruzki başka hatalarda alarak veri kaybı yada veri bütünlüğünü bozacak kodlardan kaçınalım diye, bir nevi aslında raise yazdığımız bölümde Application.Terminate; diyerek Programı kapatmış oluyoruz. geri kalan kodların çalışmasını önlemiş oluyoruz.
Kısaca
Raise = Bu satırda Kod Akışını Durdur devam etme ;)
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen thelvaci »

Rabbim cümlemizden razı olsun. Benim genellikle kritik veritabanı işlemlerinde kullandığım yöntem aşağı yukarı şu şekilde:

Kod: Tümünü seç

var
  aspDo : TADOStoredProc;
begin
  if not aConn.InTransaction then
    aConn.BeginTrans;

  aspDo := TADOStoredProc.Create(nil);
  
  try
    try
      aspDo.Connection := aConn;
      aspDo.ProcedureName := 'sp_Test';
      aspDo.Parameters.Refresh;
      aspDo.Parameters.ParamByName('@Param').Value := AValue;

      aspDo.ExecProc;
    except
      if aConn.InTransaction then
        aConn.RollbackTrans;

      raise;
    end; // try..except
  finally
    aspDo.Free;

    if aConn.InTransaction then
      aConn.CommitTrans;
  end;  // try..finally

  ShowMessage('Kayıt işlemi tamamlandı.');
end;
Yukarıdaki örnek kodda, bir connection transaction içinde değil ise ilk aşamada bir transaction başlatılıyor. İlk try..finally bloğu memory leak oluşmaması için koyduğum blok. Bu sayede aspDo nesnesini hafızadan atabiliyoruz. İçeride bir hata olur ise kod otomatikman iç try..except bloğuna geçecek ve connection rollback yapılacak, ardından raise ile bu bloğa aktarılan hata re-raise yapılarak finally kısmına dallanılmasına neden olacak. Finally bölümünde aspDo isimli nesnenin free edilmesinden sonra connection daha önce rollback edildiği için commit edilemeyecek ve bloktan çıkılacak ve ShowMessage kodu da işletilmeyecektir.!

Umarım faydalı bir örnek olmuştur.

Not: aConn isimli değişkenin bir TADOConnection örneği olduğunu ifade edeyim.
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen thelvaci »

esistem yazdı:Selam,
yeri gelmişken bende @mrmarman ve @thelvaci hocalarıma bir danışayım istedim. Aşağıdaki fonksiyonu sürekli olarak yıllardır kullanıyorum, herhangi bir sorunla karşılaşmadım şimdiye kadar fakat "raise" olayına kafam takıldı? kodun sonuna eklemem gereklimi? gerekli ise nedendir, cevap verebilirseniz memnun olurum.

Kod: Tümünü seç

function ProcEkleCommit(DBase:TIBDatabase; TransName:TIBTransaction; StoredName:String; Query:TIBQuery; Values: Array Of Variant; Out ckod:integer):Boolean;
 var
   Stored : TIBStoredProc;
   X : Integer;
begin
 TRY
  Stored:=TIBStoredProc.Create(Application.MainForm);
   with Stored do
   begin
                  Database       := DBase;
                  Transaction    := TransName;
                  StoredProcName := StoredName;
                  Prepare;
                  For x := 0 to Length(Values) - 1 Do Params[x+1].Value := Values[X];
                  ExecProc;
                  UnPrepare;
   end;
    TransName.CommitRetaining;
    ckod := Stored.Params[0].AsInteger;
                    (Query AS TIBQuery).Close;
                    (Query AS TIBQuery).Open;
                                     (Query AS TIBQuery).Locate('KOD',INTTOSTR(ckod),[]);
                    Result:=True;
 Stored.Free;
 EXCEPT
 on E: Exception do begin
 TransName.RollbackRetaining;
 Result:=False;
 MessageDlg('DİKKAT...!'+#13+StoredName+' - SP (CommitEkle) Hatası Oluştu'+#13+'Hata Tekrarlarsa, Lütfen www.xxx.com ile iletişime geçiniz.'+#13+E.ClassName + #13 + E.Message, mtInformation, [mbOK], 0);
//loglavegonder(firmaadi);
                        end;
 END;
end;
Kodunuzda gözlemlediğim bir kaç hususu paylaşayım müsaadeniz ile.
  • 1- Stored isimli TIBStoredProc türündeki nesneniz create edildikten sonra alt satırlarda hata oluşur ise bir şekilde ilgili nesneniz free edilmiyor. Bu da memory leak oluşmasına neden olur.(Gerçi owner olarak ana formu belirtmişsiniz, ana form free edilirken owner'ı olduğu nesneleri free eder ama uygulamanız açık olduğu müddetçe sürekli artan bir hafıza sızıntınız olur.)
    2- Interbase transaction nesnelerini daha önce kullanmadım ama, muhtemelen ado connection nesnesinde olduğu gibi connection'ın bir transaction içinde olup olmadığını denetlemenizi sağlayacak bir InTransaction gibi bir metoda ihtiyacınız olabilir. İlgili connection nesnesinin ve bağlandığınız veritabanının özelliklerine bağlı olarak; aynı anda birden fazla transaction başlatamıyor olabilirsiniz aynı connection içinde; ya da iç içe nested transaction başladığında buradaki kodunuz hata vermesede bir başka paralel işleyen kod bloğu bir transaction'ı rollback ettiğinde buradaki işlemlerinizde rollback'e uğrayabilir.
    3- CommitRetaining kodunuzdan sonra bir hata olursa açık bir transaction'ınız kalmadığı için RollbackRetaining kodunuz "geri alınacak bir transaction yok" gibi bir hataya neden olabilir ve işin daha da üzücü olan kısmı bu hatanın except bloğu içinde oluşmasıdır. Dolayısı ile ekrana beklediğiniz messagedlg mesajı değil başka bir mesaj çıkabilir.
Şimdilik görebildiklerim bu kadar umarım faydalı olabilmişimdir.
Kullanıcı avatarı
esistem
Üye
Mesajlar: 464
Kayıt: 02 Eki 2007 11:22
İletişim:

Re: Mad Exception bileşenini kullananlar...

Mesaj gönderen esistem »

Teşekkür ederim tuğrul bey, değerli yorumunuz doğrultusunda gerekli düzenlemeri yapıcam.
Cevapla