Handle GWS REST server errors

When a call to a Genero Web Services REST function returns a status, you can check for server errors.

The fglrestful tool generates methods for handling different types of errors on the client stub. This will vary depending on how error handling has been defined for operations on resources. For more information, see Handling application level errors.

You can expect your application code to handle the following in calls to a service:

  • Check for a successful operation response.
  • Check for known or expected errors, such as a bad request, resource not found, and so on.
  • Check for unknown or unexpected errors, such as an internal server error at runtime.

In the response from a call to a service operation, check the returned status code to handle errors. The sample code in Trapping server errors on the client side shows how you can reference the client stub to trap these errors in your client application.

Expected errors

The fglrestful tool generates constants for expected errors. When you make a call to a service, the service returns a status code to your function with a corresponding value depending on the response from the service. For example, a value of zero indicates a successful operation.

# Error codes
PUBLIC CONSTANT C_SUCCESS = 0
PUBLIC CONSTANT C_USERERROR = 1001
PUBLIC CONSTANT C_NOT_FOUND = 1002
If the value of the returned status code is over 1000, such as C_USERERROR or C_NOT_FOUND, it indicates an expected error. The GWS sets the userError record to return details. You must reference this record in your application to get more information about the error.
# generated userErrorErrorType
PUBLIC TYPE userErrorErrorType RECORD
    message STRING
END RECORD

# Forced error
PUBLIC DEFINE userError userErrorErrorType

Unexpected errors

The fglrestful tool generates the wsError record type to handle unexpected errors. If the returned status code has a value less than zero, you must reference the wsError in your application to get more information about the error.
  • If the wsError code field has a value less than zero, it indicates a GWS runtime error, such as the service not started, etc.
  • If the wsError code field returns a HTTP status code value (200-599), it indicates an error not handled in the specification of the service.
The wsError description field returns the error message.
PUBLIC DEFINE wsError RECORD
  code INTEGER,
  description STRING
END RECORD

Trapping server errors on the client side

In your module, you define a variable (wsstatus in the example) to trap the status code in the return of your function calls to the service. The recommended approach is to check the status code returned, and code to handle errors (CASE wsstatus in the sample) based on the status code.
  • If wsstatus = 0, the status code is equal to zero (clientStub.C_SUCCESS in the example) and there is no error.
  • If wsstatus > 0, the status code is greater than zero and the GWS returns a HTTP error that has been defined in the specification (openapi.json) of the service. You need to check the variable userError for the error message.
  • If wsstatus < 0, the status code is less than zero and you must check wsError for further details.
Note:

It is recommended to always handle unexpected errors (CASE OTHERWISE in the code example), as these may arise due to different transport layers.

IMPORT FGL clientStub

MAIN
   CALL myWSRESTcall()
END MAIN

# Function performs call to the client stub function 
FUNCTION myWSRESTcall()
    DEFINE rets INTEGER
    DEFINE wsstatus INTEGER

    DEFINE p_body clientStub.updateUsersRequestBodyType
    LET p_body.users_id = "4" 
    LET p_body.users_name = "new name to be decided"
    # ...

     CALL clientStub.updateUsers(p_body.*) RETURNING wsstatus, rets
     CASE wsstatus
       WHEN clientStub.C_SUCCESS
         DISPLAY "Updated the user:"
       WHEN clientStub.C_NOT_FOUND
         DISPLAY "User not found"
         DISPLAY "error reason :", clientStub.userError.message
       WHEN clientStub.C_USERERROR
         #... Expected error
         DISPLAY "status code : ", wsstatus
         DISPLAY "Error reason :", clientStub.userError.message
       OTHERWISE
         #... Unexpected GWS error
         DISPLAY "Internal error"
         DISPLAY "status code : ", wsstatus
         DISPLAY "error code   :", clientStub.wsError.code
         DISPLAY "error reason :", clientStub.wsError.description
     END CASE
END FUNCTION