Ok, we have a GPF caused by a simple code that tries to see if a string is formatted as a date.
&if keyword-all('routine-level') ne ? &then routine-level on error undo, throw. &endif function getDate returns date (strIn as longchar): if num-entries(strIn, '-') ne 3 then do: message 'throw' view-as alert-box. return error. end. return date(integer(entry(2, strIn, '-':u)), integer(entry(3, strIn, '-':u)), integer(entry(1, strIn, '-':u))). end. define variable dt as date. dt = getDate('noc/007-') no-error. message dt skip error-status:error skip error-status:num-messages view-as alert-box.
This is on 10.2B, well the customer seems to be on 10.1C and upgrade isn't an option so please don't start 'singing' you should upgrade :(
If the input parameter is changed to character then we do get the error, 'invalid entry 3' but we do have to work with longchar cause we do not know what is there really :(
Funny thing is trying to get around that I'm attempting to throw an error if num-entries aren't what we expect, it must have been the time when 'structured error handling' entered the stage cause no error seems to be thrown, I can't catch it, doing the assignment with no-error leaves the error-status:error set to false, num-messages is 0.
Maybe I'm not understanding what you wrote correctly, but this code doesn't crash when I run it on 10.2B. Or does it only crash on 10.1C? What platform do you see the crash on?
I cannot reproduce a GPF in 10.2B08 win32 or solaris9. I don't have ready access to 10.1C.
I tried that code on my Win10 64 machine with 10.2b7 and 10.1C4, no GPF...
My fault, the code as posted does not crash but taking out the check on num-entries from the begining of the function make it crash on 10.2. Its 10.2B, linux and if it makes any difference is on batch mode.
/usr/dlc/bin/bpro -p custom.p
Batch processing will be performed using:
OpenEdge Release 10.2B as of Mon Dec 14 17:00:19 EST 2009
root@daf20e454fca:/opt/akera# *** Error in `/usr/dlc/bin/_progres': munmap_chunk(): invalid pointer: 0x0000000000d164b0 ***
Received signal 6; handling as SIGHUP. (4375)
HANGUP signal received. (562)
However, the question is why doesn't that return error throw the error out of the function block... this doesn't work as expected (well, at least for me) either in 10.2 nor in 11.3.
&if keyword-all('routine-level') ne ? &then routine-level on error undo, throw. &endif &if keyword-all('block-level') ne ? &then block-level on error undo, throw. &endif function fError returns character (): return error. end. procedure pError: return error. end. message fError() skip error-status:error view-as alert-box. run pError. catch e as Progress.Lang.Error : message 'error' view-as alert-box. end catch.
Umm... are you sure you want to be running 10.2B?
Doesn't crash for me - 10.2B08 Windows GUI / 10.2B08 Windows ChUI / 10.2B0874 Linux x64 pro / bpro (CentOS7).
Maybe also session:date-format and session:code-page play a role?
Replying by email seems to still be broken, at least for me :(
I’m sure I don’t want to run on 10.2B, as said the client seems to be still on 10.1C and update is not an option… 10.2B is the ‘oldest’ instance I’ve could found to play with and that is on Linux :(
However, this does consistently GPF on 10.2B/Linux regardless of the date-format.
function getDate returns date (strIn as longchar):
if num-entries(strIn, '-') ne 3 then do:
message 'throw' view-as alert-box.
return date(integer(entry(2, strIn, '-':u)),
integer(entry(3, strIn, '-':u)),
integer(entry(1, strIn, '-':u))).
define variable dt as date.
dt = getDate(‘noc/007-') no-error.
On newest version that throws and error for that string because entry 3 is not there.
Trying to get around this I’m checking if the string is a somehow valid date by looking at the num-entries and if not valid I need to throw an error so we can catch that later on but then I find that this seems to be an impossible task, uncommenting the block does give me the ’throw’ message but then ‘return error’ statement doesn’t do anything… no error is being thrown when that function is being called, is that a known issue, maybe the expected behaviour? Have to agree it’s hard to be sure how this error handling works lately, you think you got it but then looks like it’s not like that :(
You can not return error from function:
From 11.7.2 online help for FUNCTION
To return an error to the caller from a user-defined function, you can:
Migrate from using a user-defined function defined within a procedure to using a method defined within a class.
Use the ROUTINE-LEVEL ON ERROR UNDO, THROW statement in conjunction with the THROW option of the UNDO statement or the ON ERROR phrase in the user-defined function block.
Use the THROW option of the UNDO statement or the ON ERROR phrase from a CATCH block (CATCH statement) within the user-defined function block.
Invoke the STOP statement to raise the STOP condition in the caller.
That is really something I must have been overlooked, are you saying that RETURN ERROR from a function stoped working at some point and now the only way to do that is to use THROW?
I might be wrong but I do think that was perfectly valid once and most probably code like that is to be found in quite large numbers out there, not everyone moved to OO and structured error handling and when you have to support 'dinossaurs' it's not always easy :(
Anyway, in that case the documentation for RETURN statement is wrong and need to be adjusted...
<<Causes an ERROR condition in the calling block. This can cause the ERROR condition to be raised for the following statements in the caller:
The RUN statement for a procedure
Any statement that invokes a user-defined function
Any statement that invokes a method of a class
Any statement that invokes the NEW function (classes) to instantiate a class (invoking the specified constructor and all other constructors for the class hierarchy)
Any statement that accesses a property defined with a property accessor
You can use the ERROR option in a procedure, database trigger block, class-based method, constructor, property accessor method, or user-defined function. However, you cannot use the ERROR option in a user-interface trigger block to raise ERROR outside of the trigger block.
RETURN ERROR from a function has never worked by raising error in the caller, as would happen with a procedure. Well, I shouldn't say never - we fixed it to work that way for a couple of months (a while ago) and then had to undo it due to customer feedback. RETURN ERROR from a function will cause it to return the Unknown value. But error is not raised in the caller.
But yes, the newer "structured error handling" constructs do work, like THROW.
Yup - it looks like the doc is wrong. This will be all fixed in the new Error Handling book that we are working on. We will also have to fix it in the ABL reference. Thanks for pointing that out.
Laura, would you care to elaborate on the customer feedback that cause you to rollback the change a little bit?
Marian, it is not you. You are totally correct, and I couldn't agree with you more. But here's the story:
Unfortunately, RETURN ERROR was coded this way from the beginning. I don't know why, but someone at the time obviously thought it made sense. That is ancient history, but it remained like that for many years.
So when we realized that it was inconsistent, we changed it. However, customers, including one major one, as well as our internal tooling team, had already coded against the behavior that it returned the Unknown value. Therefore, by raising error in the caller, this would now kick them out of their block and completely break the existing code. It is understandable that they did not want this behavior to change. There was a huge quantity of code (we were told) that was potentially broken. And we do make the claim that we will never introduce regressions. So we had to back out the change.
So there you have it. We would now entertain the idea of adding a compiler option to issue a compiler warning or error when we see this. And luckily, because we now have structured error handling, you can code it to work the way you want.
Thanks for your feedback.