Link to home
Start Free TrialLog in
Avatar of Balshe
Balshe

asked on

Try Except for the whole Application

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 ??


Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

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. :-)
Avatar of Balshe
Balshe

ASKER


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?
Avatar of Balshe

ASKER

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?
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!)
Avatar of Balshe

ASKER

know this is a question that i want an answer for


so  what should i do ?



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 https://www.experts-exchange.com/questions/20680238/Global-Error-handler.html

Regards,

Oktay
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
Your worked harder for me Balshe ;)
Avatar of Balshe

ASKER

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?
Avatar of Balshe

ASKER

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.






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.)
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?

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
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.
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 ?
"and hi accepted answer includes" should be
"and hi(s) accepted anser includes" ;)
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.
download another really working example from:
page:        http://www.geocities.com/esoftbg/
  link:        Q_21147656.zip

It is a super solution !!!!
@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.
Avatar of Balshe

ASKER

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
SOLUTION
Avatar of esoftbg
esoftbg
Flag of Bulgaria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@Workshop_Alex,

please first download and test
and then do Comment ....
;-))
Avatar of Balshe

ASKER



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

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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 ....
;-))
@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.
O.k. @Workshop_Alex, I understood what you mean.  :-))
Avatar of Balshe

ASKER

Thanks to you all guys
That was helpful