Errors occuring during the execution of post-processing ruby scripts are often difficult to track. Generally, the exceptions raised by the different methods in the script do not convey useful information to identify the location of the error and its meaning. A majority of the errors are related to the definition of data, but one sometimes needs to go deep into the code, adding “print” statements to identify the mistake (wrong file name, reference to a non-existing group, missing parameter for an extraction of a failure criterion...).
To ease debugging, a “PrjExcept” class, deriving from ruby standard “Exception” class is defined in “PGR/prjExcept.rb” file. This class stored information related to the location of the exception, and optionnally additional information that may help to identify the source of the problem. The “dump” method of “PrjExcept” class writes to standard output stream the call stack and additional information related to an exception. For example, in “static.rb” script, one has the following code:
postList.each do |p|
begin
p.initCalcSteps()
p.calculate("Static")
rescue Exception => x
printf("Failed Post object %s with ID %s\n",p.to_s,p.postID())
PrjExcept.debug(x)
end
end
The “PrjExcept.debug(x)” inscrution calls a class method in “PrjExcept” class that write to standard output detailed information about the exception. The information corresponds to the type of exception, the location in program where exception has been raised (call stack), and additional contextual messages.
An example of output provided by the “PrjExcept.debug(x)” statement is as follows:
Exception of class PrjExcept
DUMPING exception:
PrjExcept CALL STACK (most recent call first):
1: from static.rb:53:in ‘<main>’
2: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/DATA/staticLoadCasesData.rb:251:in ‘loop’
3: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/PGR/dbAndLoadCases.rb:453:in ‘loopOnStaticCases’
4: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/PGR/dbAndLoadCases.rb:453:in ‘each’
5: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/PGR/dbAndLoadCases.rb:488:in ‘block in loopOnStaticCases’
6: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/DATA/staticLoadCasesData.rb:252:in ‘block in loop’
7: from static.rb:64:in ‘block in <main>’
8: from static.rb:64:in ‘each’
9: from static.rb:67:in ‘block (2 levels) in <main>’
10: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/PGR/post.rb:52:in ‘calculate’
11: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/PGR/postConnect.rb:269:in ‘calc_0’
12: from C:/Users/ferespost/Documents/TESTSAT/RUBY/PROJECT/PGR/postConnect.rb:249:in ‘extractConnectLoads’
PrjExcept MESSAGES:
Obtains nil resF Result for "MPCFRC"
Failed to calculate calc_0
param : interfaceDef => {"ifName"=>"pan_MX/bar_MXPY (MPCFRC)", "grpNameA"=>"pan_MX", "grpNameB"=>"bar_MXPY", "method"=>"MPCFRC"}
param : bRedistr => false
param : csId => 5
param : direction => [0.0, 0.0, 1.0]
param : type => M6
param : criteria => [["Gapping", "Gapping.gmsh", "Gapping", "xl_Gapping", {"FoS"=>1.56, "Pmin"=>7200.0, "Lg"=>0.003}], ["Sliding", "Sliding.gmsh", "Sliding", "xl_Sliding", {"FoS"=>1.25, "Pmin"=>7200.0, "Cf"=>0.25}], ["Insert", "Insert.gmsh", "Insert", "xl_Insert", {"FoS"=>1.56, "PSS"=>3300.0, "QSS"=>4500.0}]]
Sometimes an exception is not related to an error in scripts or data definition. For example, when the justification involves structure configurations in which part of the structure is missing (panel removed) the corresponding post-processing may fail and raise an exception. Then, it is advisable to comment out the call to “PrjExcept.debug(x)” in order to keep standard output as clean as possible:
postList.each do |p|
begin
p.initCalcSteps()
p.calculate("Static")
rescue Exception => x
printf("Failed Post object %s with ID %s\n",p.to_s,p.postID())
# PrjExcept.debug(x)
end
end
Alternatively, debugging information can be output only for a small selection of load cases and post-processing objects. To do this, appropriate tests must be inserted in the code above.
The call stack and several messages that may help to understand the error can be read. These messages are created in the different ruby methods where the exception is created. For example, the previous exception is created in “extractConnectLoads” of “PostConnect” class as follows:
if resF==nil then
raise PrjExcept.new(format("Obtains nil resF Result for \"%s\"",extractionMethod))
end
if resM==nil then
raise PrjExcept.new(format("Obtains nil resM Result for \"%s\"",extractionMethod))
end
The messages are added in “calc_0” method by the following instructions:
...
rescue Exception => x
x2=PrjExcept.new(x)
x2.addLine(format("Failed to redistribute connection loads"))
Util::addParamsToPrjExcept(x2," param : ",interfaceDef)
raise x2
...