Resolved Error Throw/catch

JoseKreif

Member
Progress Version = 10.2b
Operating System = Linux, RedHat Enterprise



We are apparently experiencing a "More than one
found with a UNIQUE find" when the program runs.

I've checked the source code and the find statement uses "No-Error", so that error should not show up. I've also put some logic in there to show if it's happening there, and so far so good.

Code:
find i1w where i1w.i1anbr = oe_lns.i1anbr and
            i1w.plntno = oe_hdr.os_plntno no-error.


We have a program thatcan send emails. So I call that to email myself so I know when it happened and with what values for the find.

Code:
if avail i1w then
...

else if ambiguous i1w then
  run [email program].
else
...


This error must be happening else where. I've used keywords to search the source code in the repository. I've looked up and down. A couple other programmers have looked too.


--

I'm wondering if it is possible to catch the error from the parent program.

Our parent program is called when user selects it on the menu. It calls 2 programs

Code:
run ar/rpu.p.
run ar/rr.p.


Would it be possible to wrap those 2 in a error catch? like

Code:
try {
run ar/rpu.p.
run ar/rr.p.
}

catch TheError as Progress.Lang.SysError:
v-error-msg = TheError:GetMessage(1).
if v-error-msg = "More than one i1w records found by a unique FIND.
(3166)" then
/* EMAIL MYSELF THE VALUES USED FOR FIND */
end catch.
 
Last edited:

Stefan

Well-Known Member
Add:

Code:
do on error undo, throw:
   run ar/rpu.p.
   run ar/rr.p.
end.

You could also add:

Code:
routine-level on error undo, throw.

As a top level statement, note that this does not catch for each blocks (among others), to catch those you need to add on error undo, throw explicitly or upgrade to OpenEdge 11 in which you can use
Code:
block-level on error undo, throw.

Both these options can also be turned on for everything with a switch on the compile statement.

Note that this is not a silver bullet and program flow may alter unexpectedly.
 

JoseKreif

Member
Add:

Note that this is not a silver bullet and program flow may alter unexpectedly.

Would you suggest I try

Code:
do on error undo, throw:
   run ar/rpu.p.
   run ar/rr.p.
end.


Also, if the error was to occur, would the program return prematurely, or will it continue at the same line the error occurred?
 

TheMadDBA

Active Member
You could always enable client logging and at least get the line number of the program that is throwing the error. Helpful for testing and debugging but not so much to prevent the error.
 

JoseKreif

Member
You could always enable client logging and at least get the line number of the program that is throwing the error. Helpful for testing and debugging but not so much to prevent the error.

Would you be able to guide me on enabling client logging?

I started logging all the includes and calls to other programs that all happen withing the parent program. It's getting messy. Still no luck on finding this rogue "find".


|-ar/updlog.p
|---------------ar/rpu.p
|--------------------util/stdsvi.svi
|--------------------util/shead.svi
|--------------------util/secure.p
|--------------------util/shead.p
|--------------------ar/rpu_01.p
|-------------------------------util/stdsvi.svi
|--------------------ar/rpu_02.p
|---------------------------util/stdsvi.svi
|---------------------------ar/rpu_05.p
|---------------------------util/prmchk.p
|---------------------------util/pkgupdt.p
|---------------------------rebates/rebcalc.p
|--------------------------------------------rebates/rcalc.i
|--------------------ar/rpu_03.p
|-------------------------------util/stdsvi.svi
|-------------------------------util/shead.svi
|--------------------tables/getperd.p
|--------------------ar/rpu_04.p
|-------------------------------util/stdsvi.svi
|
|---------------ar/rr.p
|-------------------util/stdsvi.svi
|-------------------util/shead.svi
|-------------------util/stdout_x.i
|-------------------ar/rr0.i
|-------------------ar/rr.i
|-------------------util/stdout_c.i
|-------------------util/stdout_2.i
|-------------------util/stdout_c.i
|-------------------util/secure.p
|-------------------util/shead.p
|-------------------tables/getperd.p
|-------------------ar/rr_01.p
|-----------------------------util/stdsvi.svi
|----------------------------util/shead.svi
|-----------------------------tables/getperd.p
|-------------------ar/rr_02.p
|-----------------------------util/stdsvi.svi
|-----------------------------util/stdout.svi
|-----------------------------util/shead.svi
|-------------------ar/rr_03.p
|-----------------------------util/stdsvi.svi
|-----------------------------util/stdout.svi
|-----------------------------ar/rr_gld0.i
|-----------------------------ar/rr_gld.i
|-------------------ar/rr_04.p
|-----------------------------util/stdsvi.svi
|-----------------------------util/stdout.svi
|-----------------------------util/comt_del.p
|-------------------ar/rr_05.p
|-----------------------------util/stdsvi.svi
|-----------------------------util/stdout.svi
|-----------------------------util/comt_del.p
|_______________________________________________
 

TheMadDBA

Active Member

JoseKreif

Member
Two KBs to help:

Progress KB - How to turn on 4GL tracing within WebSpeed, AppServer and the 4GL Client?
Progress KB - What are the possible values for the -logentrytypes startup parameter in OpenEdge

If you are running an interactive application you should be able to use -debugalert and you will get a popup message with the current stack trace. Line numbers will match the line numbers provided when you compile with debug-list and not a standard listing.

Thank you.

I had to do a lot of reading and playing around to figure out exactly what to do.

In my test copy of our database, I enabled client logging and wrote a program to cause the error. It looks pretty accurate.

joseph@Devel -> cat log.txt
[16/03/10@12:47:01.420-0600] P-013262 T-4160472784 1 4GL -- Logging level set to = 1
[16/03/10@12:47:16.920-0600] P-013262 T-4160472784 1 4GL -- (Procedure: '/home/joseph/lp/mkerr.p' Line:1) More than one i1w records found by a unique FIND. (3166)
joseph@Devel ->

I'll present this to my manager for permission on changing our production database settings.


The only problem is that the information is kind of flawed if the error happens in a include

Main Program Example
Code:
def var aqqa as int.
def var aee as int.

def var eea as int.
def var ea as int.

{/home/joseph/lp/mkerr.i}

def var ae as int.
def var aqq as int.
def var aq as int.
def var qa as int.

the include
Code:
display "23".
display "23".
display "23".
display "23".
display "23".
display "23".
display "23".
display "23".

find i1w where i1w.i1anbr = "050101234BCG".
display "23".
display "23".
display "23".
display "23"

[16/03/10@13:40:30.578-0600] P-016273 T-4159907536 1 4GL -- (Procedure: '/home/joseph/lp/mkerrm.p' Line:18) More than one i1w records found by a unique FIND. (3166)

Program name and line are off, but gets me closer to finding the error, I guess.
 
Last edited:

Osborne

Active Member
To find the exact lines compile your program as such and the line numbers in the resultant text file will match the logging lines:
Code:
COMPILE prog1.p SAVE DEBUG-LIST c:\temp\prog1lines.txt.
 

Stefan

Well-Known Member
I can highly recommend using PCT to automate your builds (coupled with Ant and Jenkins CI), with one extra parameter it will also automatically spit out a directory with debug-listings.
 

TheMadDBA

Active Member
It is pretty accurate except for certain errors thrown by dynamic queries/objects from time to time.

Keep in mind that this will increase the write activity to disk... depending on which log entries you enable. And you would want to have a unique log file path for different users of your application. Keeping it to errors only shouldn't cause an issue though.
 

JoseKreif

Member
I can highly recommend using PCT to automate your builds (coupled with Ant and Jenkins CI), with one extra parameter it will also automatically spit out a directory with debug-listings.

We are bringing on a new DBA to replace the one we lost. We he starts, I will recommend he look into this if he doesn't know about it already.


To find the exact lines compile your program as such and the line numbers in the resultant text file will match the logging lines:
Code:
COMPILE prog1.p SAVE DEBUG-LIST c:\temp\prog1lines.txt.

1 def var aqqa as int.
2 def var aee as int.
3
4 def var eea as int.
5 def var ea as int.
6
7
8
9 display "23".
10 display "23".
11 display "23".
12 display "23".
13 display "23".
14 display "23".
15 display "23".
16 display "23".
17
18 find i1w where i1w.i1anbr = "050101234BCG".
19 display "23".
20 display "23".
21 display "23".
22 display "23".
23
24
25 def var ae as int.
26 def var aqq as int.
27 def var aq as int.
28 def var qa as int.

I see. This might come in handy

And you would want to have a unique log file path for different users of your application. Keeping it to errors only shouldn't cause an issue though.

Oh, I didn't know you could do it based on users. Is that easy to setup?

I'm not a DBA, so going a little outside my comfort zone.
 
Last edited:

TheMadDBA

Active Member
A lot of how you do it depends on your application and how users connect. If the users are logging in through CHUI/Terminal access you can change your script to make the file name/path based on their user id or home directory. Something like -clientlog $HOME/client.log or -clientlog /tmp/${USER}.log (this will not work in parameter files).

Assuming you have a test system I would just try it there instead of turning it on in production. If you don't have a test system then talk to your boss about getting one in place :) Always best to try these kind of things out where there is no risk to production.
 

JoseKreif

Member
A lot of how you do it depends on your application and how users connect. If the users are logging in through CHUI/Terminal access you can change your script to make the file name/path based on their user id or home directory. Something like -clientlog $HOME/client.log or -clientlog /tmp/${USER}.log (this will not work in parameter files).

Assuming you have a test system I would just try it there instead of turning it on in production. If you don't have a test system then talk to your boss about getting one in place :) Always best to try these kind of things out where there is no risk to production.

I figured /tmp/${USER}.log would work, and yes, not in the pf file, since that is basically plain text, not shell.

Yes, I got a Development server to try it on. I'll see how It goes. Thank you


This is the piece that gets our users into their main menu, I believe.

$DLC/bin/mpro -D 100 -crc -nb 100 /u/ffi/data/ff -db /u/ffi/data/report3 -p startup.p $*

So I'll just mod it to

$DLC/bin/mpro
-clientlog /tmp/4GL-LOG/${USER}.txt -D 100 -crc -nb 100 /u/ffi/data/ff -db /u/ffi/data/report3 -p startup.p $*


EDIT:

actually, I might be able to make this only log for the user who recieves this error.

Shell code
Code:
if [[ USER == "jdoe" ]]; then
$DLC/bin/mpro
-clientlog /tmp/4GL-LOG/${USER}.txt -D 100 -crc -nb 100 /u/ffi/data/ff -db /u/ffi/data/report3 -p startup.p $*
else
$DLC/bin/mpro -D 100 -crc -nb 100 /u/ffi/data/ff -db /u/ffi/data/report3 -p startup.p $*
fi
 
Last edited:

JoseKreif

Member
I talked to my manager. I get to present it to the team and implement it on Monday.

I will setup our startup script so that we are only logging for the user who runs the program(s) in question, and using cron, I will purge the logs every night.
I will just keep this up until we find something.

Thanks for the help. I probably wouldn't of discovered "-clientlog" otherwise.
 

Rob Fitzpatrick

ProgressTalk.com Sponsor
Thanks for the help. I probably wouldn't of discovered "-clientlog" otherwise.
Since you followed my earlier advice ;) and downloaded the documentation, you can find out about -clientlog and lots of other useful client startup parameters in the Startup Command and Parameter Reference manual.

You can learn all about log entry types in the Debugging and Troubleshooting manual.

A couple of other useful client startup parameters to look at for troubleshooting/tuning are -y and -yx.
 
Top