1. In lens-errors.conf create a new entry under the section corresponding to the module in which you want to return the new Error Code.

  2. Make the corresponding entry in the Enum for error codes corresponding to that module. This ensures a more readable and less error prone way of using the errorCode unique id.

  3. Create a new instance of LensException using the Enum that you defined in step 2 and throw it where you want to return the new Error Code

 

See the explanation in the following section and Example  below for more details.

 

How it works?

On startup Lens Server initializes an instance of ErrorCollection  from ErrorCollectionFactory using ErrorCollectionFactory.createErrorCollection(

This process involves reading lens-errors.conf file and overriding it with lens-errors-override.conf (if any)  Each conf file follows the format of a typesafe config file  and roughly has a layout like below

lens-errors.conf
# Define HTTP status codes
BAD_REQUEST = 400
INTERNAL_SERVER_ERROR = 500


# lensCommonErrors: Defined for lens-api module and expected to be used by every other module

lensCommonErrors = [
  {
    errorCode = 1001
    httpStatusCode = ${INTERNAL_SERVER_ERROR}
    errorMsg = "Internal Server Error."
 }
{
  errorCode = 1002
  httpStatusCode = ${BAD_REQUEST}
  errorMsg = "XML invalid: %s"
}

#........ more errors for lens-api module
]

# lensServerErrors: Defined for lens-server module
lensServerErrors = [
  {
    errorCode = 2001
    httpStatusCode = ${BAD_REQUEST}
    errorMsg = "Session id not provided. Please provide a session id."
 }
  {
    errorCode = 2002
    httpStatusCode = ${BAD_REQUEST}
    errorMsg = "Query is not provided, or it is empty or blank. Please provide a valid query."
 }
]
#........

Each entry in the file defines

  1. an errorCode - A unique numerical identifier to identify the error. This should be unique across all errors as ErrorCollections uses this value to get the corresponding instance of LensError.

  2. an httpStatusCode representing the status code which will be set on the Response in case of error.

  3. A string / template -  This can either be a plain string(e.g."Session id not provided. Please provide a session id.") or a string template (e.g. "XML invalid: %s")  to which arguments can be provided.
  4. payloadClass - class representing the payload. Lens will use reflection to get the Class for the corresponding string. In lens-errors.conf errors defined with different error codes must have different payloadClass. These are used to create JAXBContext to serialize and deserialize the responses.

Corresponding to each section in the lens-errors.conf we have enums defined for errors of that module e.g. LensCommonErrorCode for lens-api module and LensServerErrorCode for lens-server module. When developers want to throw an exception they use these enums to create an instance of  LensException

Example

For an entry like below in the lens-errors.conf

lensCubeErrorsForMetastore = [
{
  errorCode = 3101
 httpStatusCode = ${BAD_REQUEST}
  errorMsg = "Problem in submitting entity: %s"
}
]
we have defined following entry in the enum LensCubeErrorCode in lens-cube module
 
ERROR_IN_ENTITY_DEFINITION(3101, 100),

 

Here 3101 is the errorCode which is same as the errorCode defined in the lens-errors.conf entry. When throwing exception we use this to create an instance of LensException as below.

throw new LensException(LensCubeErrorCode.ERROR_IN_ENTITY_DEFINITION.getLensErrorInfo(), " Ref column: "  + getName() + " does not have any chain_ref_column defined");

Here the second argument will be used to format the template provided in errorMsg in lens-errors.conf

 

Once the Exception is thrown Lens uses JAX-RS's  ExceptionMapper capability to convert exceptions to appropriate response. The Class LensExceptionMapper implements the ExceptionMapper interface and for a given exception it prepares the appropriate Response. It sets the Http Status code of the response using 

exception.getLensAPIResult.getHttpStatusCode()

and it sets the response to 

exception.getLensAPIResult

as the entity. If any payloadClass is registered then it will be used by the JAXBContext  to serialize the response.

 

  • No labels