Presentation is loading. Please wait.

Presentation is loading. Please wait.

DEV-4: Structured Error Handling in the ABL

Similar presentations


Presentation on theme: "DEV-4: Structured Error Handling in the ABL"— Presentation transcript:

1 DEV-4: Structured Error Handling in the ABL
Structured error handling in 101c DEV-4: Structured Error Handling in the ABL Sarah Marshall QA Architect

2 Structured Error Handling -- Agenda
Make some preliminary comments naming: Traditional v Structured Assuming a background in Traditional error handling (the old way) Based on OO model, but you do not need an OO app or OO programming to use it This is an overview of what it is. This is not how to apply it to your app – see DEV-22 Overview of the old and new Catching errors Raising errors The FINALLY block Changes to be aware of

3 Traditional Error Handling Model
Structured Error Handling Traditional Error Handling Model Behavior handled at the statement level Failure cases handled in varied and inconsistent ways Basics of Error handling Statements that fail can raise error Behavior handled at the statement level Behavior handled locally at the block level All blocks have error handling (implicit or explicit) Application can return error to its caller Difficulties with traditional Inconsistent error handling Procedures, UDF’s, built-in methods, application errors (error situations, failure cases) Errors must be handled locally Errors do not propagate automatically Can communicate info about an error to the caller by writing code BUT Cannot pass along the error itself, cannot pass it out to the enclosing block in one compilation unit. Application errors limited to: RETURN ERROR [error string] No way to add additional information to errors NO-ERROR / ERROR-STATUS Behavior handled locally at the block level Errors must be handled locally, do not propagate automatically ON ERROR, UNDO { LEAVE | RETRY | …} No way to add additional information to application errors Application can return error to its caller RETURN ERROR [error string]

4 E A Bit About Blocks Outer Block ON ERROR UNDO, RETRY Inner Block NEXT
Structured Error Handling A Bit About Blocks Outer Block ON ERROR RETRY NEXT LEAVE RETURN UNDO, Review of block behavior ABL is transactional and block-based in that code is always executes in the context of some block. Examples: Procedure, internal procedure, trigger etc. Block types: routine level Named routines – executed by name Ex: Procedure, internal procedure, udf, method the highest level and do not support do on error statement based block types Initiated with an ABL statement Execute inline during the execution of the program Ex: REPEAT, FOR loop, DO TRANSACTION Blocks execute inside other blocks, beginning with the main block. INNER / OUTER Ex: Internal procedure, FOR EACH Ex: REPEAT, DO TRANSACTION Make the point that errors cannot be passed from the INNER Ex: Method, DO ON ERROR to the outer block – only to the caller!! Default error handling – flow of control UNDO – transactional block, protect your data on error undo RETRY directives infinite loop protection Iterating loop – NEXT Non-iterating loop – LEAVE Can override on statement based block with the ON ERROR phrase Inner Block E

5 Let’s look at the code PROCEDURE ErrorBlock:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). FIND FIRST Order WHERE Order-Num = 1002. END. END PROCEDURE. Outer block  PROCEDURE…END PROCEDURE Inner block  FOR EACH Customer…END First FIND  handled with NO-ERROR Second FIND  handled by DO ON ERROR for the FOR EACH block.

6 Let’s look at the code PROCEDURE ErrorBlock:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). FIND FIRST Order WHERE Order-Num = 1002. END. END PROCEDURE. Outer block  PROCEDURE…END PROCEDURE Inner block  FOR EACH Customer…END First FIND  handled with NO-ERROR Second FIND  handled by DO ON ERROR for the FOR EACH block.

7 Let’s look at the code PROCEDURE ErrorBlock:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). FIND FIRST Order WHERE Order-Num = 1002. END. END PROCEDURE. Outer block  PROCEDURE…END PROCEDURE Inner block  FOR EACH Customer…END First FIND  handled with NO-ERROR Second FIND  handled by DO ON ERROR for the FOR EACH block.

8 Let’s look at the code PROCEDURE ErrorBlock:
FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). FIND FIRST Order WHERE Order-Num = 1002. END. END PROCEDURE.

9 Let’s look at the code PROCEDURE ErrorBlock:
FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). FIND FIRST Order WHERE Order-Num = 1002. END. END PROCEDURE.

10 Let’s look at the code PROCEDURE ErrorBlock:
FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). FIND FIRST Order WHERE Order-Num = 1002. END. END PROCEDURE.

11 Structured Error Handling Model – 10.1C
Overview of Structured error handling – An error is and error is an error – Unifies System and Application errors Consistent with other languages (Java, C#) – Try / Catch model No need for TRY – already have a way to initiate a block of code 1. CATCH to handle errors – syntax (defines an error variable as the error type) Unifies Application and System errors (like FIND fails) OpenEdge runtime – previously Progress Runtime – ABL Virtual Machine Application errors – create the error objects you application needs with the information it requires. 2. Built-in object for you to extend and create customized error objects syntax (using inheritance in the same way as other user-defined classes in the ABL) Facilities to propagate errors up the call stack – centralized error routine 3. could communicate info about an error to your caller…but not the error itself, and not to an enclosing block within the compilation unit – example syntax (enhancment to UNDO, throw an error object you have or instantiate one right here) Benefits of Structured error handling Co-exists with traditional error handling – will show this a little later (will point out integration points) Leverages object-oriented language features Applies to procedural and object-oriented programming models Application and system errors handled the same way CATCH blocks to handle all error types CATCH err AS Progress.Lang.Error Ability to create user-defined application errors myError INHERITS Progress.Lang.AppError Facilities to propagate errors up the call stack UNDO, THROW <error object>

12 E Catching Errors Enclosing Block ON ERROR UNDO, RETRY NEXT
Structured Error Handling Catching Errors Enclosing Block ON ERROR UNDO, RETRY NEXT LEAVE RETURN Outer/inner – enclosing / associated Examples. Ex: Internal procedure, FOR EACH Ex: REPEAT, DO TRANSACTION Ex: Method, DO ON ERROR Appears after all other statements in associated block Multiple CATCH blocks allowed Executing CATCH block Associated block is undone Executes the CATCH block for the correct error type After CATCH, execution continues with the default flow-of-control for an error condition (RETRY, NEXT, LEAVE) Explicity is ignored BUT can override in the CATCH Associated Block E Catch

13 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer: FIND FIRST Order WHERE Order-Num = 1001. CATCH e AS Progress.Lang.SysError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE OBJECT e. END CATCH. END. END PROCEDURE. Enclosing block  PROCEDURE…END PROCEDURE Associated block  FOR EACH Customer…END Error on FIND  handled by CATCH block

14 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
FIND FIRST Order WHERE Order-Num = 1001. CATCH e AS Progress.Lang.SysError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE OBJECT e. END CATCH. END. END PROCEDURE.

15 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
FIND FIRST Order WHERE Order-Num = 1001. CATCH e AS Progress.Lang.SysError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE OBJECT e. END CATCH. END. END PROCEDURE.

16 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
FIND FIRST Order WHERE Order-Num = 1001. CATCH e AS Progress.Lang.SysError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE OBJECT e. END CATCH. END. END PROCEDURE.

17 Object Hierarchy Progress.Lang.Object Progress.Lang. Error
Structured Error Handling Object Hierarchy Progress.Lang.Object The OO portion of the talk – object hierarchy makes all this possible! How do I know what type of error to catch? Every object has as its root PLO Interface (makes it possible to catch errors that are not OpenEdge errors) (more applicable with .NET – Advanced UI) PLP is the root of built-in error objects PLE is all system generated errors – errors raised by the AVM, OpenEdge runtime (FIND fails) PLA is any error your application requires – raised by the programmer Any error you define! What does it mean to catch different kinds of errors? SysError – all system generated errors AppError – all errors raised by the applications (or distinguish and catch specific user-defined types) ProError – catches all errors – then CAST to get to specific error info. interface – catches all errors as well, including third party errors that implement the interface, such as System.Exception Progress.Lang. Error <<interface>> Progress.Lang.ProError Progress.Lang.AppError Progress.Lang.SysError User-Defined Error Objects Progress.Lang. SoapFaultError

18 Error Objects Properties available on ProError
Structured Error Handling Error Objects Properties available on ProError What can you do with error objects? What do you do once you’ve caught it? A lot of this is what you see on the ERROR-STATUS system handle. NumMessages GetMessage GetMessageNum Additional properties: ReturnValue Severity CallStack - default is off, for performance - turn on with session attribute - also a startup parameter - same info you’d get with debugalert. Additional Method – this is how you build your apperror with the specific info your app requires. AddMessage RemoveMessage User-defined error objects – anything you want!! *** STOP FOR QUESTIONS *** NumMessages, Severity, CallStack Methods available on ProError GetMessage(), GetMessageNum() Additional Methods and Properties on AppError AddMessage(), RemoveMessage() ReturnValue

19 E THROW Throwing Errors Enclosing Block ON ERROR UNDO, RETRY LEAVE
Structured Error Handling Throwing Errors Enclosing Block ON ERROR UNDO, RETRY LEAVE NEXT RETURN What does it mean to THROW an error. The same rules of UNDO happen first throws the error out of the associated block (in which the error occurred) raises the error in the enclosing block  This is the bit that could not happen before!!! Before – pass info about the error, but you still had to handle the erro – couldn’t pass the error itself, or defer handling it to another point. UNDO, THROW changes the default error behavior of the statement based blocks Propagate errors up to a generic error handling routine Associated Block E THROW

20 Throwing Errors Overrides default ON ERROR of routine level blocks
Structured Error Handling Throwing Errors Overrides default ON ERROR of routine level blocks Change the default error behavior of the routine-level blocks Or explicitly THROW an error wherever your application requires an error to be raised. THROW raises error ROUTINE-LEVEL ON ERROR UNDO, THROW Explicitly throws (or re-throws) an error UNDO, THROW <error object>

21 Let’s look at the code PROCEDURE ErrorBlock:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). END. END PROCEDURE. Previous way of handling error, using traditional error handling

22 Let’s look at the code ROUTINE-LEVEL ON ERROR UNDO, THROW.
Structured Error Handling Let’s look at the code ROUTINE-LEVEL ON ERROR UNDO, THROW. PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, THROW: FIND FIRST Order WHERE Order-Num = 1001. END. END PROCEDURE. PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, LEAVE: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN MESSAGE ERROR-STATUS:GET-MESSAGE(1). END. END PROCEDURE. Handling the error with UNDO, THROW Error from the FIND is handled by the block, which is UNDO THROW  throws out of FOR EACH block to the PROCEDURe block Default error handling for the PROCEDURE block is UNDO, THROW because of the ROUTINE-LEVEL declarative  error raised on the PROCEDURE block is thrown out to its caller.

23 Let’s look at the code ROUTINE-LEVEL ON ERROR UNDO, THROW.
PROCEDURE ErrorBlock: FOR EACH Customer ON ERROR UNDO, THROW: FIND FIRST Order WHERE Order-Num = 1001. END. END PROCEDURE.

24 E Returning Errors Enclosing Block Caller RETURN ERROR
Structured Error Handling Returning Errors Caller Enclosing Block RETURN ERROR Another way to raise an error where your application requires an error to be raised… Interoperability Wherever RETURN ERROR is supported: Methods, constructors, procedures Manufactures a Progress.Lang.AppError, Returns it to the caller CAUTION Thrown errors cannot cross an AppServer™ boundary Generates a run-time error How to handle this – same as today. 1. handle the error 2. RETURN ERROR with optional string 3. CATCH the error in the client  RETURN ERROR will still cause an AppError to get created on the client. Associated Block E

25 Returning Errors Return a Progress.Lang.AppError with error string
Structured Error Handling Returning Errors Return a Progress.Lang.AppError with error string Options on RETURN ERROR: Return an error string – RETURN-VALUE function or ReturnValue property of the AppError Return an error object – Progress.Lang.AppError or user-defined error object *** STOP FOR QUESTIONS *** RETURN ERROR [error string] Returns error of type error-object with RETURN ERROR <error object> Cannot return an error object from the AppServer

26 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer: FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN RETURN ERROR NEW OrdNotFoundError(“1001”). END. END PROCEDURE. MAIN.P runs ErrorBlock in the persistent procedure handle hPersProc. Error on the FIND is handled locally with NO-ERROR. If error is raised, return an error condition to the caller  in this case return a user-defined error object CustNotFoundError which takes the Order number of the order that could not be found (to perhaps build an error string specific for that Order) In the caller the user-defined error is handled with a CATCH for Progress.Lang.AppError

27 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
FIND FIRST Order WHERE Order-Num = 1001 NO-ERROR. IF ERROR-STATUS:ERROR THEN RETURN ERROR NEW OrdNotFoundError(“1001”). END. END PROCEDURE. /* MAIN.P */ RUN ErrorBlock IN hPersProc. CATCH e AS Progress.Lang.AppError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE e. END CATCH.

28 A Few Words About NO-ERROR
Structured Error Handling A Few Words About NO-ERROR NO-ERROR Continues to suppress errors at the statement level Here’s the bit about interoperability… 1. Continues to suppress error conditions Sets ERROR-STATUS:ERROR to TRUE 2. Handle thrown errors 3. Messages from the error objects are written to the ERROR-STATUS system handle Caveat User-defined application error data is lost. NO-ERROR Can handle errors raised via UNDO, THROW NO-ERROR Converts information from error objects to ERROR-STATUS

29 What that means is… Handle any error NO-ERROR Generate any error
Structured Error Handling What that means is… Handle any error What this means – any error, any error handling What THIS means is that you can add structured error handling a little at a time and gradually migrate your application to a new model. Or not handled… Errors written to output device AVM deletes the error object – if not caught (if caught then delete or re-throw) ON ERROR flow-of-control for that block executes *** STOP FOR QUESTIONS *** NO-ERROR DO ON ERROR CATCH Generate any error RETURN ERROR UNDO, THROW ERROR condition

30 Always executes on success or failure
Structured Error Handling And FINALLY… Enclosing Block A sub-block of the associated block REPEAT, FOR, DO ON ERROR, DO TRANSACTION Routine-level blocks (method, constructor, destructor, procedure, udf) Useful for clean-up code Appears after all other statements in associated block, including any CATCH blocks Always executes, on success or failure On each iteration of an iterating loop In error case…Before LEAVE, NEXT, RETRY, RETURN or THROW on associated block After FINALLY execution continues ON ERROR flow-of-control if error condition Default non-error behavior if no error condition Always executes on success or failure Associated Block Finally Catch

31 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
Structured Error Handling Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer: FIND FIRST Order WHERE Order-Num = 1001. CATCH e AS Progress.Lang.SysError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE OBJECT e. END CATCH. FINALLY: /* clean up code */ END FINALLY. END. END PROCEDURE. Enclosing block  PROCEDURE…END PROCEDURE. Outer block  FOR EACH Customer…END CATCH block to handle errors that occur FINALLY block to handle clean up code If there is no Order 1001 then error will be raised, the CATCH block will execute, the FINALLY block will execute and execution continues with the next customer If there is an Order 1001 then there is no error condition, the FINALLY block executes and execution continues with the next customer

32 Let’s look at the code PROCEDURE ErrorBlock: FOR EACH Customer:
FIND FIRST Order WHERE Order-Num = 1001. CATCH e AS Progress.Lang.SysError: MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX. DELETE OBJECT e. END CATCH. FINALLY: /* clean up code */ END FINALLY. END. END PROCEDURE.

33 Changes in Behavior Does Not Raise Error Raises Error
Structured Error Handling Changes in Behavior With traditional error handling… Does Not Raise Error Procedure raised error, AVM raised error when failures occur, Anything else that writes to ERROR-STATUS did not - built-in methods - built-in functions - setting some attributes NOTE about the change in behavior. If error is raised then UNDO occurs – undoable work that occurred prior to the failure will be undone, which did not happen before. hSrv:CONNECT(…)NO-ERROR. IF ERROR-STATUS:NUM-MESSAGES > 0 THEN: MESSAGE “Connect Failed!” VIEW-AS ALERT-BOX. With structured error handling… Raises Error hSrv:CONNECT(…). CATCH err AS Progress.Lang.SysError: END CATCH.

34 What About User-defined Functions?
Structured Error Handling What About User-defined Functions? Q: Will RETURN ERROR in a udf raise error in the caller? Just finished saying that you can handle all your errors the same way… So what about user-defined functions… A: No. Q: Is there another way to raise error from a udf? A: YES!

35 Raising Error from User-defined Functions
Structured Error Handling Raising Error from User-defined Functions With RETURN ERROR… Does Not Raise Error in Caller User-defined functions behave the way they always have RETURN ERROR will not raise error in the caller It will return the unknown value. Throwing an error from a user-defined function will raise error in the caller. FUNCTION foo RETURNS INTEGER (): RETURN ERROR. END FUNCTION. With structured error handling… Raises Error in Caller ROUTINE-LEVEL ON ERROR UNDO, THOW. FUNCTION foo RETURNS INTEGER (): UNDO, THROW NEW AcmeError(). END FUNCTION. FUNCTION foo RETURNS INTEGER (): CATCH e AS AcmeError: UNDO, THROW NEW AcmeError(). END. END FUNCTION.

36 In Summary Uniform model for handling error conditions
Structured Error Handling In Summary Uniform model for handling error conditions More flexibility for application specific errors Traditional and structured error handling models co-exist Powerful error handling consistent with other languages

37 Structured Error Handling
? Questions

38 Structured Error Handling
Thank You

39 Structured Error Handling


Download ppt "DEV-4: Structured Error Handling in the ABL"

Similar presentations


Ads by Google