问题描述
假设我有三个(或多个)程序,其中一些程序相互调用,如下所示,任何一个都可能失败。如果任何一个失败,我希望主程序立即记录失败并终止程序。
在Delphi中使用什么正确的语法将异常传回每个前面的过程调用?
更好的是,如果有人可以帮助我获得主程序的Try / except块,以确定哪个位失败!
三个程序的样本伪代码和主程序可能如下所示。
(我认为我理解与加注有关的原则,但是想要一些帮助实际的语法和什么代码我应该使用)
/////////// ////////////////////////
过程DoProcA
begin
try
begin
{stuff}; //可能会
结束的东西;
除了
在E上:异常do
begin
LogError('A'中的错误);
end // on E
end; // try
////////////////////// ////////////
过程DoProcB
begin
try
begin
做ProcC; //另一个可能失败的proc
{other stuff}
end;
除了
对于E:异常do
begin
LogError('B'中的错误);
end // on E
end; // try
////////////////////// ////////////
过程DoProcC
开始
尝试
开始
{做东西} //甚至更多的可能会失败
结束;
除了
对于E:异常do
begin
LogError('C'中的错误);
end // on E
end; // try
////////////////////// //////////////
//主程序
begin
try
DoProcA;
DoProcB;
{其他东西}
除了
{这里我想要能够像
那样做,如果A,B或C失败然后
开始
LogError(A,B或C中的某个地方出现故障);
application.terminate;
end;}
end; //尝试
结束。
各功能重新加注记录后捕获的异常,例如:
过程DoProcA;
begin
try
{stuff}; //可能会下降
的东西,除了
在E:Exception do
begin
LogError('A in');
加注//< - -
end;
结束
结束
过程DoProcB;
begin
try
DoProcC; //另一个可能失败的进程
{other stuff}
除了
在E:Exception do
begin
LogError('B'中的错误);
加注//< - -
end;
结束
结束
过程DoProcC;
begin
try
{Do stuff} //甚至更多的东西可能会失败
除了
在E:Exception do
begin
LogError ('C'中的错误);
加注//< - -
end;
结束
结束
begin
try
DoProcA;
DoProcB;
{other stuff}
除了
对于E:异常do
begin
LogError('A,B或C'中的某处失败);
//Application.Terminate; //这不是有用的,除非Application.Run首先被调用
end;
结束
结束。
如果您希望主程序识别WHICH功能失败,则需要将该信息传递给异常链接,例如:
键入
MyException = class(Exception)
public
WhereFunc:串;
构造函数CreateWithFunc(const AWhichFunc,AMessage:String);
结束
构造函数MyException.CreateWithFunc(const AWhichFunc,AMessage:String);
begin
继承Create(AMessage);
WhereFunc:= AWhichFunc;
结束
过程DoProcA;
begin
try
{stuff}; //可能会下降
的东西,除了
在E:Exception do
begin
raise MyException.CreateWithFunc('DoProcA',E.Message); //< - -
end;
结束
结束
过程DoProcB;
begin
try
DoProcC; //另一个可能失败的进程
{其他东西}
除了
在E:MyException do
begin
raise; //< - -
end;
on E:Exception do
begin
raise MyException.CreateWithFunc('DoProcB',E.Message); //< - -
end;
结束
结束
过程DoProcC;
开始
尝试
{做东西} //更多的东西可能会失败
除了
在E:异常do
开始
加MyException.CreateWithFunc('DoProcC',E.Message); //< - -
end;
结束
结束
begin
try
DoProcA;
DoProcB;
{other stuff}
除了
在E:MyException do
begin
LogError('Failure in'+ E.WhichFunc +':'+ E.Message) ;
结束
在E:Exception do
begin
LogError('Failure at other else:'+ E.Message);
结束
结束
结束。
或:
code> type
MyException = class(Exception)
public
WhereFunc:String;
构造函数CreateWithFunc(const AWhichFunc,AMessage:String);
结束
构造函数MyException.CreateWithFunc(const AWhichFunc,AMessage:String);
begin
继承Create(AMessage);
WhereFunc:= AWhichFunc;
结束
过程DoProcA;
begin
try
{stuff}; //可能会下降
的东西,除了
在E:Exception do
begin
raise MyException.CreateWithFunc('DoProcA',E.Message); //< - -
end;
结束
结束
过程DoProcB;
begin
try
DoProcC; //另一个可能失败的进程
{other stuff}
除了
在E:Exception do
begin
Exception.RaiseOuterException(MyException.CreateWithFunc('DoProcB' E.Message)); //< - -
end;
结束
结束
过程DoProcC;
开始
尝试
{做东西} //更多的东西可能会失败
除了
在E:异常do
开始
加MyException.CreateWithFunc('DoProcC',E.Message); //< - -
end;
结束
结束
var
例外:异常;
begin
try
DoProcA;
DoProcB;
{other stuff}
除了
在E:Exception do
begin
Ex:= E;
重复
如果Ex是MyException然后
LogError('失败在'+ MyException(Ex).WhichFunc +':'+ Ex.Message)
else
LogError (其他地方失败:+ Ex.Message);
Ex:= Ex.InnerException;
,直到Ex = nil;
结束
结束
结束。
Assume I have three (or more) procedures, some of which call each other, as shown below, any one of which can fail.
If any one of them do fail I want the 'main' program to immediately log the failure and terminate the program.
What is the correct syntax to use in Delphi to 'pass back' an exception to each preceeding procedure call?
Even better if someone can help me to get the main program's Try/except block to identify which bit failed!
Sample pseudo code of the three procedures and the main program might look like below.
(I think I understand the principle, something to do with 'raise', but would like some help with the actual syntax and what code I should use)
//////////////////////////////////////
Procedure DoProcA
begin
try
begin
{stuff}; //stuff that might fall
end;
except
on E : Exception do
begin
LogError ('error in A');
end //on E
end;//try
//////////////////////////////////////
Procedure DoProcB
begin
try
begin
Do ProcC; //another proc that might fail
{other stuff}
end;
except
on E : Exception do
begin
LogError ('error in B');
end //on E
end;//try
//////////////////////////////////////
Procedure DoProcC
begin
try
begin
{Do stuff} //even more stuf fthat might fail
end;
except
on E : Exception do
begin
LogError ('error in C');
end //on E
end;//try
//////////////////////////////////////
//Main programo
begin
try
DoProcA;
DoProcB;
{other stuff}
except
{here I want to be able to do something like
if failure of A, B or C then
begin
LogError ('Failure somewhere in A, B or C');
application.terminate;
end;}
end; //try
end.
Have each function re-raise the caught exception after logging it, eg:
Procedure DoProcA;
begin
try
{stuff}; //stuff that might fall
except
on E : Exception do
begin
LogError ('error in A');
raise; // <-- here
end;
end;
end;
Procedure DoProcB;
begin
try
DoProcC; //another proc that might fail
{other stuff}
except
on E : Exception do
begin
LogError ('error in B');
raise; // <-- here
end;
end;
end;
Procedure DoProcC;
begin
try
{Do stuff} //even more stuff that might fail
except
on E : Exception do
begin
LogError ('error in C');
raise; // <-- here
end;
end;
end;
begin
try
DoProcA;
DoProcB;
{other stuff}
except
on E: Exception do
begin
LogError ('Failure somewhere in A, B or C');
//Application.Terminate; // this is not useful unless Application.Run is called first
end;
end;
end.
If you want the main procedure to identify WHICH function failed, you need to pass that information down the exception chain, eg:
type
MyException = class(Exception)
public
WhichFunc: String;
constructor CreateWithFunc(const AWhichFunc, AMessage: String);
end;
constructor MyException.CreateWithFunc(const AWhichFunc, AMessage: String);
begin
inherited Create(AMessage);
WhichFunc := AWhichFunc;
end;
Procedure DoProcA;
begin
try
{stuff}; //stuff that might fall
except
on E : Exception do
begin
raise MyException.CreateWithFunc('DoProcA', E.Message); // <-- here
end;
end;
end;
Procedure DoProcB;
begin
try
DoProcC; //another proc that might fail
{other stuff}
except
on E : MyException do
begin
raise; // <-- here
end;
on E : Exception do
begin
raise MyException.CreateWithFunc('DoProcB', E.Message); // <-- here
end;
end;
end;
Procedure DoProcC;
begin
try
{Do stuff} //even more stuff that might fail
except
on E : Exception do
begin
raise MyException.CreateWithFunc('DoProcC', E.Message); // <-- here
end;
end;
end;
begin
try
DoProcA;
DoProcB;
{other stuff}
except
on E: MyException do
begin
LogError ('Failure in ' + E.WhichFunc + ': ' + E.Message);
end;
on E: Exception do
begin
LogError ('Failure somewhere else: ' + E.Message);
end;
end;
end.
Or:
type
MyException = class(Exception)
public
WhichFunc: String;
constructor CreateWithFunc(const AWhichFunc, AMessage: String);
end;
constructor MyException.CreateWithFunc(const AWhichFunc, AMessage: String);
begin
inherited Create(AMessage);
WhichFunc := AWhichFunc;
end;
Procedure DoProcA;
begin
try
{stuff}; //stuff that might fall
except
on E : Exception do
begin
raise MyException.CreateWithFunc('DoProcA', E.Message); // <-- here
end;
end;
end;
Procedure DoProcB;
begin
try
DoProcC; //another proc that might fail
{other stuff}
except
on E : Exception do
begin
Exception.RaiseOuterException(MyException.CreateWithFunc('DoProcB', E.Message)); // <-- here
end;
end;
end;
Procedure DoProcC;
begin
try
{Do stuff} //even more stuff that might fail
except
on E : Exception do
begin
raise MyException.CreateWithFunc('DoProcC', E.Message); // <-- here
end;
end;
end;
var
Ex: Exception;
begin
try
DoProcA;
DoProcB;
{other stuff}
except
on E: Exception do
begin
Ex := E;
repeat
if Ex is MyException then
LogError ('Failure in ' + MyException(Ex).WhichFunc + ': ' + Ex.Message)
else
LogError ('Failure somewhere else: ' + Ex.Message);
Ex := Ex.InnerException;
until Ex = nil;
end;
end;
end.
这篇关于嵌套异常的正确方法是什么? - 使用Delphi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!