I have several instances where a user defined query is entered into a character string variable.  The query is then used to control selection of records during a process navigating through the database.  Because the user can make a mistake, I employ a two step process. 
Test query format of the query, cInputExp:
  bError := ErrorBlock( {|e| Break(e)} )        // install new error handling code block
  BEGIN SEQUENCE
    IF ( EMPTY( cInputExp ) )
      xType := "U"
    ELSE
      xResult := &cInputExp.
      xType   := VALTYPE( xResult )
    ENDIF
  RECOVER USING e
    xType := "U"
  ENDSEQUENCE
  ErrorBlock(bError)                            // reinstall old error handler
  RETURN xType
This process checks the syntax of the query but cannot validate all variable names used because the the short-cut evaluation process of the macro compiler.
Then within the data extraction loop the following is done:
  bSaveErrorBlock := ErrorBlock( {|e| Break(e) } )
  BEGIN SEQUENCE
  DO WHILE .......
     IF eval(bQuery).......
     ENDIF
     SKIP
  ENDDO
  RECOVER
    ErrorBlock(bSaveErrorBlock)
  END SEQUENCE
The above code does capture the error and prevent a run time error but hides what the actual error is.  I am wondering how to properly use the code to provide information as to what the error actually was and the program stack/line that caused the error.  I see the example in the documentation using "RECOVER use oError".  Are the any other examples of how to best provide this.  I know Express++ does this when trapping errors in the DC_GetRefresh() process.  Are there any other good examples of how best to use the Error object so the nature of the error can be provided back to the user to assist in correcting the query.
			
			
									
									
						Specialized error handling
- 
				Cliff Wiernik
- Posts: 605
- Joined: Thu Jan 28, 2010 9:11 pm
- Location: Steven Point, Wisconsin USA
- Contact:
Re: Specialized error handling
do you have a XppError.LOG File ...Cliff Wiernik wrote:I see the example in the documentation using "RECOVER use oError".
Are the any other examples of how to best provide this.
what oError Property exist is in your XppError.LOG like
oError:description
oError:operation
oError:args
Code: Select all
  BEGIN SEQUENCE
     FieldPut(nPos,xValue)
  RECOVER USING oError
     lRet := .F.
     IF NIL <> oError
        AADD(aError, {aStruct[i][DBS_NAME],cType,aStruct[i][DBS_LEN],aStruct[i][DBS_DEC],;
                  CHR(13)+CHR(10) ,;
                  xValue, oError:description } )
     ENDIF
  ENDSEQUENCEgreetings by OHR
Jimmy
						Jimmy
Re: Specialized error handling
Try this:
			
			
									
									Code: Select all
LOCAL bError := ErrorBlock( {|e| (DCMSGBOX 'Invalid expression:', cInputExp), Break(e)} )  The eXpress train is coming - and it has more cars.
						- 
				Cliff Wiernik
- Posts: 605
- Joined: Thu Jan 28, 2010 9:11 pm
- Location: Steven Point, Wisconsin USA
- Contact:
Re: Specialized error handling
I looked at the many places in express that do this.  I will create something like used for dc_getrefresh().  I need to know specifics on the error, not just that it has an error.  I do that already.  The problems is this is just generic at this point.  Need to know what items is not correct and on what line, in case some other error occurs.  I don't want to loose all error information which is what I have now.
Thanks for the info.
			
			
									
									
						Thanks for the info.
Re: Specialized error handling
Code: Select all
LOCAL bError := ErrorBlock( {|e| DC_InspectObject(e), Break(e)} ) The eXpress train is coming - and it has more cars.
						- 
				Cliff Wiernik
- Posts: 605
- Joined: Thu Jan 28, 2010 9:11 pm
- Location: Steven Point, Wisconsin USA
- Contact:
Re: Specialized error handling
Thanks.  I will generate an error and look at what is available.  Did not think about that.
			
			
									
									
						
