Solved

Try  Except for the whole Application

Posted on 2004-09-28
29
469 Views
Last Modified: 2010-04-05
Hi

i think i'm gonna have to make it up to you . but you should answer this question as i think ,so that nobody can delete this question

can you till me if there is some think like Try  Except for the whole Application and any kind of error that might be generated by any procedure or thread or class related to the application ??


0
Comment
Question by:Balshe
  • 8
  • 7
  • 6
  • +3
29 Comments
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12168746
Well, that's a nasty trick to give points to someone else. But hey... If you don't give points to the FIRST person who provides the correct answer then that would be pretty suspicious and you could be disqualified for that by EE.

This means that if someone says that the answer is by using the Application.OnException to capture the unhandled exceptions, then you would have to reward that person. (And this event will give you the exception object so you know what kind of exception occurred. The ExceptObject and ExceptAddr will also be very useful. And for a real global exception handler, just hook into ExceptProc to add your own exception handler routine. For an example, search for the function InitExceptions in the SysUtils unit.)

But hey, I won't spoil your fun. I won't give an answer. :-)
0
 
LVL 1

Author Comment

by:Balshe
ID: 12168863

I don't care much about points, I only care about learning. And it was something like a challenge. I always try to make a challenge in every thing I want to do, it makes it much more fun and gets the best out of a person. Don’t you think? :)

and it's a deal


so do you care to provide me with a code?
0
 
LVL 1

Author Comment

by:Balshe
ID: 12168915
and by the way i didn't know about the regulations because i was absence for about a year and didn't know that this way became illegal :(  

i will give the points to the first suitable answer ,OK?
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12169032
Okay. Then I won't answer it. I'll give ceoworks a chance to answer it. But if others will be as nice as me... I don't know.
And I do agree that it sucks that the rules are enforced a bit stronger than it used to be. The rules have never changed, though. It's just that the moderators are now more aware about these tricks.
Also be aware that by giving expert points to experts, you're supporting them to get a free premium account that would normally cost them $9.95 per month. (If they even bothered to pay.) Basically, by giving away points you're giving away money from the EE owners. ;-) I've earned my premium account this month already but it would be unfair if experts gets lots of points just because you like them. 500 is the maximum per question that you can give away. You can give it all to the same expert or divide it over multiple experts. But whatever you choose, you just can't ever give more than 500 points, unless you split a question in multiple questions.

And I understand why EE is enforcing this. The EE database must be a professional resource for developers all over the world. A worldwide FAQ with all answers. It would just be a waste if it was full with silly questions and Q's like "points for xxx" since those would end up in the system too. Pure pollution. I like EE because it's a useful resource full good solutions. I'd like it less if it was too polluted. (And I've actually left for a while because it got too polluted in the past.)
I know you want to reward ceoworks for his help but this way is not the solution. Maybe just ask the EE staff to delete this question too. I have no problem with that. Or else accept the first valid answer. (And I did NOT answer it!)
0
 
LVL 1

Author Comment

by:Balshe
ID: 12169146
know this is a question that i want an answer for


so  what should i do ?



0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12169387
Hi Balshe,

You can use TApplicationEvents component(exist in "Additional Tab"). Or you can use Madshi's madExcept component. This is more professional solution i think.

You can take a look at the accepted answer from http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20680238.html

Regards,

Oktay
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12169821
And thanks for all the things you did for to give me these points. But you should know that having so much Expert Points is not much more important than to find the right answer and to be helpfull for someone. All these experts here are trying to share their knowledge and experience with the others. Experts are not robots, they can't know everything about every topic. You can be sure that we are learning something new everyday by following these programming groups. As the Alex said, we are using the premium services without to pay $9.95. But not just for this. We only need to earn 3000 points per month. Take a look at the profiles of the other experts. Most of them earned much more than 3000 points in this month.. Why are they still answering ? Just for to share !! But of course, point system is so important for the future of this great platform(Ex-Ex).

Nice to hear that your problem solved..

Cheers,

Oktay Sancak
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12169833
Your worked harder for me Balshe ;)
0
 
LVL 1

Author Comment

by:Balshe
ID: 12169925
Hi ceoworks
You know about my program now
It’s about main thread that lunches many threads.
the thing is that if I lunch like 20 threads it's ok ,but if I lunch 30 threads then the whole program crashes ,and I don't want that -infact no body does :)  -,so where should I use this ? And I’m talking about “Ferruccio68" Answer is it good here? and how to use it with threads ? in the main thread?

 And I want to ask another question about dynamic arrays in Delphi, do you guys think I should ask it here or another question?
0
 
LVL 1

Author Comment

by:Balshe
ID: 12169975
ceoworks it's just that i'm a man of my word and i said that i'm gonna give 700 points while i didn't know that the limit is 500 ,and didn't know that i made i violation to the system -i feel that i'm in matrix :)    -  and i know that you deserve more points for your answer ,but you know i have to Obey the rules.






0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12169990
Basically, the best thing would be to generate a separate post for every question you have. You have one about threading and one about dynamic arrays. Those are two other Q's next to this one. :-)
The drawback of asking multiple Q's is of course that it costs points. And if you don't have premium services, the amount of points you can spend is very limited. That's why some people ask multiple Q's in one post. Others do that because it's just convenient. But it's better to have a separate post for every question you have. (Besides, that allows you to reward more people in a EE-acceptable way.)
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12170427
Hi, i was contacted by mail about this Q.

You said that you have a Main thread that executes other threads...
I guess that this is related to a your previous Q about Thread terminate notification...
What you must let us know is what these threads do, because it seems that you loads a lot of memory during the thread execution, as your threads are processing files (this means that lot of files are processed simultaneously)...
How do you execute these threads? Are you synchronizing them?

0
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 12170860
actually, to answer to your question (ceoworks answered but not quite with source code) you can use
Application.OnException
something like this:

TMyForm = class(TForm)
...
private
   FLastHandleException: TExceptionEvent;
end;
...
procedure TMyForm.FormCreate(Sender: TObject);
begin
   FLastHandleException := Application.OnException;
   Application.OnException := NewHandleException;
end;

procedure TMyAppForm.FormDestroy(Sender: TObject);
begin
   Application.OnException := FLastHandleException;  //just to be a good neighbour
end;

procedure TMyForm.NewHandleException(Sender: TObject; E: Exception);
begin
  //here you can handle the exceptions globally for any exception in your program...
 //you have the same E:Exception that you would use in a try..except on E:Exception do...
end

about the points... is simple, 500 is the most points for one question, that's it, you can also give a good grade
probably the problem is that nowadays many users post easy 500 points questions... that's not supposed to be that way
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12171099
I have once created a simple unit that catches any unhandled exceptions. Here's the code:

unit untExceptionLogging;
interface
implementation
uses SysUtils, untDebug;
type TExceptHandler = procedure( ExceptObject: TObject; ExceptAddr: Pointer ); far;
var OldExceptProc: Pointer;

procedure ExceptHandler( ExceptObject: TObject; ExceptAddr: Pointer ); far;
begin
  if not Assigned( ExceptObject ) then begin
    WriteLn( Log, '*** Exception at address ', HexDisplayPrefix, IntToHex( Integer( ExceptAddr ), 8 ), '.' );
  end
  else if ExceptObject.InheritsFrom( Exception ) then begin
    WriteLn( Log, '*** Exception "', Exception( ExceptObject ).Message, '" at address ', HexDisplayPrefix, IntToHex( Integer( ExceptAddr ), 8 ), '.' );
  end
  else begin
    WriteLn( Log, '*** Exception class ', ExceptObject.ClassName, ' at address ', HexDisplayPrefix, IntToHex( Integer( ExceptAddr ), 8 ), '.' );
  end;
  if Assigned( OldExceptProc ) then TExceptHandler( OldExceptProc )( ExceptObject, ExceptAddr );
end;

initialization
  OldExceptProc := ExceptProc;
  ExceptProc := @ExceptHandler;
finalization
  ExceptProc := OldExceptProc;
end.

The unit untDebug is a unit that creates a log file (textfile) where I can write all kinds of information to. This unit doesn't have anything in it's interface part since it doesn't need to have anything there. It just has to catch unhandled exceptions and write them to a file. It works quite well in console applications and DLL's but if you're creating an application (with TApplication) then the TApplication object will catch any exception that's created by your code. So, for those exceptions you still have to use the OnException method of the application.

There's one other trick that can be useful to handle exceptions. Create your class methods with the safecall directive and override the SafeCallException method. (But don't forget to call the inherited SafeCallException afterwards for the default error handling.)
type
  TSafeCallLogInterfacedObject = class( TInterfacedObject )
  public
    function SafeCallException( ExceptObject: TObject; ExceptAddr: Pointer ): HResult; override;
    procedure Crash; safecall;
  end;

function TSafeCallLogInterfacedObject.SafeCallException( ExceptObject: TObject; ExceptAddr: Pointer ): HResult;
begin
  // Do something with ExceptObject and ExceptAddr
  Result := inherited SafeCallException( ExceptObject, ExceptAddr );
end;

procedure TSafeCallLogInterfacedObject.Crash;
begin
  raise Exception.Create( 'Crash.' ); // This will trigger the SafeCallException method.
end;

The advantage of this trick is that it also tells you which class generated the nasty exception. Delphi has included this method for the COM support because COM can't just send over exceptions just like that. This method is meant for those special cases where you want some special exception handling with a COM call. But of course it's also open for other uses. But it only gets triggered for safecall methods. You don't need the crash method in above example. It is there AS an example.

But ceoworks mentioned Madshi's madExcept that you can find at http://www.madshi.net/ and it is a good component set for handling exceptions. Good answer, ceoworks :-) Basically, we're just repeating what is said in that other thread.
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 4

Expert Comment

by:ceoworks
ID: 12171995
I wasn't have enough time so i couldn't provide much more details about the solution and just told you the tools that you can use for this. But i referenced the kretzschmar's answer and hi accepted answer includes some usefull explanation too.. So i thought that it would be better than my quick post :)

Nice code sample Alex :). BlackTigerX, your code shows what the TApplicationEvents component is already does. Isn't it ?
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12172019
"and hi accepted answer includes" should be
"and hi(s) accepted anser includes" ;)
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12174076
program Try_Except;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  try
    Application.Run;
  except
    on E : Exception do
    begin
      //........ Your code here ....
    end;
  end;
end.
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12174259
download another really working example from:
page:        http://www.geocities.com/esoftbg/
  link:        Q_21147656.zip

It is a super solution !!!!
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12175040
@ceoworks, I know I gave an explanation, but you provided a link to EE where this topic is already widely explained. That should be just as clear. ;-)

@esoftbg, also a nice solution. But with console applications or DLL's that would be less useful. Okay, put code between try-except blocks to keep it safe.
0
 
LVL 1

Author Comment

by:Balshe
ID: 12176991
answering  Ferruccio68  about what threads do:

each thread is loading array of record from a table it reaches about 999999  as a maximum value for array size

it then process each record in the array and depending on some calculations it saves data in a table or add,update or add and update  a record in another table
0
 
LVL 12

Assisted Solution

by:esoftbg
esoftbg earned 50 total points
ID: 12177246
> @esoftbg, also a nice solution. But with console applications or DLL's that would be less useful. Okay, put code between try-except blocks to keep it safe.

@Workshop_Alex,

page:        http://www.geocities.com/esoftbg/
  link:        Q_21147656.zip

is not like the previous my Comment, it is about Exception Hooking ....
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12177260
@Workshop_Alex,

please first download and test
and then do Comment ....
;-))
0
 
LVL 1

Author Comment

by:Balshe
ID: 12177453


 Workshop_Alex: could you write a sample unit that uses  "untExceptionLogging"  ?

0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 250 total points
ID: 12177940
@esoftbq, I did download that file and all I noticed is this line: Application.OnException := On_App_Exception;
Actually, that's not real special. It's what the ApplicationEvents component is actually doing. :-)

@Balshe, sure. The most simplest way:

Unit I_Use_untExceptionLogging;
interface
uses untExceptionLogging;
implementation
end.

It's really that simple. No code to start it up and no code to break it down is required. Just including that unit in your uses clause anywhere will add it's functionality to the global application. All you have to do, though, is do something logical with the exception you receive in the ExceptHandler. Normally, the SysUtils unit with it's ExceptHandler method would capture the exception, show a dialog box displaying the error and then HALT the application. Just look how SysUtils handles exceptions.
The untExceptionLogging is actually handling the most outer layer for exceptions. If an exception isn't captured by any other exception handler then it will finally end up at the untExceptionLogging unit and be handled by the ExceptHandler method. If an excption is captured by e.g. a try-except block, you won't ever receive it here, though. Consider it the last line of defence.

There are quite a few things you can do in the ExceptHandler method. But since this ExceptHandler method is the last line of defence, you have to remember that if it causes an exception itself, then who's going to handle that one? ;-) But I used it once to capture an annoting exception dialog that occurred with one application I had. One in 10 times it would just show the dialog and instead of spending days finding the error I used an hour to write this unit with thise code for ExceptHandler:

procedure ExceptHandler( ExceptObject: TObject; ExceptAddr: Pointer ); far;
begin
  Halt(1);
end;

The result? If now an exception happens, it will terminate the application but it will not show the exception to the user. This is very useful for an unattended process that needs to perform some action without any user interaction.

For a sample application that uses this unit, and the SafeCall exception handler, look at this:

program TestExceptionHandlerUnit;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  untExceptionLogging in 'untExceptionLogging.pas',
  untDebug in 'untDebug.pas';

type
  TDummy = class( TInterfacedObject )
  public
    function SafeCallException( ExceptObject: TObject; ExceptAddr: Pointer ): HResult; override;
  published
    procedure Dummy; safecall;
  end;

procedure TDummy.Dummy;
begin
  raise Exception.Create( 'Hello' );
end;

function TDummy.SafeCallException( ExceptObject: TObject; ExceptAddr: Pointer ): HResult;
var
  Name: string;
  Address: string;
begin
  Name := Format( 'Safecall exception in class %s: ', [ ClassName ] );
  Address := Format( 'Address %s%s', [ HexDisplayPrefix, IntToHex( Integer( ExceptAddr ), 8 ) ] );
  if not Assigned( ExceptObject ) then begin
    WriteLn( Log, Name, Address );
  end
  else if ( ExceptObject is Exception ) then begin
    WriteLn( Log, Name, ( ExceptObject as Exception ).Message, ' - ', Address );
  end
  else begin
    WriteLn( Log, Name, 'Type ', ExceptObject.ClassName, ' - ', Address );
  end;
  Result := inherited SafeCallException( ExceptObject, ExceptAddr );
end;

begin
  TDummy.Create.Dummy;
end.

Above console application raises an exception on purpose. Since the Dummy method is a Safecall method, it will capture the exception raised in this method and you can do something with it. However, since it's still an exception afterwards, the ExceptHandler method will capture this exception next. Thus, the result is that two lines of code are written to the log file.
If you remove the safecall directive from the dummy method, then the SafeCallException will not catch the exception...

If you're interested in that untdebug, then download it from http://www.workshop-alex.org/Sources/Debug/Debug.zip which is the source of a special debug DLL. It's a trick I've used with several of my applications. I include the untDebug in my applications and this unit checks if a DLL called debug.dll is located in the same folder as the executable (or DLL!) itself. If not, it doesn't do anything. But if the DLL is there, it tells the DLL to create two log files for debugging purposes. One file that has a timestamp for every line, another without timestamps. Thus, my testenvironment has this DLL and thus I get lots of log messages. The customer doesn't have the DLL so he doesn't get them. But if it's really required to test something at the customers site, I just bring the DLL with me on a floppy or so, put it in the folder of the application and run it so I can generate log information at their site. And then remove it again because I don't want to bother them with developer logs...
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12178418
@Balshe asked:
> can you till me if there is some think like Try  Except for the whole Application and any kind of error that might be generated > by any procedure or thread or class related to the application ??

My solution does exactly that !

//........

@Workshop_Alex wrote above:
> @esoftbq, I did download that file and all I noticed is this line: Application.OnException := On_App_Exception;
> Actually, that's not real special. It's what the ApplicationEvents component is actually doing. :-)

But I don't care about, because his comment does not matter: My solution works fine with or without @Workshop_Alex's comment ....
;-))
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12178772
@esoftbq, as I said, a nice solution. :-) Sure, it works nice. I've used it too in quite a few of my applications before I discovered the ApplicationEvents component. Yet I also have to deal with simple console applications that don't use any forms, or DLL's that don't use any forms. In those situations, your solution doesn't work! Besides, ceoworks gave a link where that solution was also suggested.

In DLL's it is especially nasty since exceptions can be real troublesome in DLL's. Which is why I use interfaces in combination with DLL's. Basically, most of my DLL's export only one function called something like "function GetSomeObject(OptionalParameter: TWhatever): ISomeObject;" and then all other DLL calls are done through the interface that this function returns. Since I always use safecall for methods in interfaces, I can also use that safecallException override method to respond to exceptions in my own class. It allows me to log the exception but also tells me which class generated the exception. (And it's almost COM-like.)

And the ExceptHandler is used to just close my application more silently on exceptions. If there is an unhandled exception somewhere then log it, but don't tell the user in a dialog box! It's quite annoying if your unattended scheduler starts some executable and this executable raises an exception. It will just keep on running until someone clicks the OK button and on an unattended system this could take quite a long time...

But for standard GUI applications your solution is just fine.
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12178884
O.k. @Workshop_Alex, I understood what you mean.  :-))
0
 
LVL 1

Author Comment

by:Balshe
ID: 12200078
Thanks to you all guys
That was helpful



0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now