MuleSoft Integration Platform Basics: “Enhancing Monitoring and Logging: Error Handling & Log Saving”- Part 5
This article has been prepared by our Salesforce Engineer, Atharva Toke, member of the Thinqloud Engineering team.
Welcome to the Fifth installment of our series focusing on MuleSoft basics. In this segment, we will delve into the process of Error logging, handling of the error for various scenarios and where to find the saved logs in Anypoint Studio.
- A Mule Flow to handle the error with the function of “On Error Propagate” to send the response of the error to the source HTTP Listener.
Create a Mule Project:-
- Create a Mule Project:In Anypoint Studio, go to File > New > Mule Project.
- Enter a name for your project and click Finish.
Configure a Source:-
- In the Mule Palette view, select “HTTP Listener” as the source.
- Drag it onto the Studio canvas.
- Set Path to the desired path for the listener.
- Click the plus sign (+) next to the Connector configuration field to configure a global element that can be used by all.
- Set Host to the desired host (e.g., 0.0.0.0).
- Set Port to the desired port (e.g., 8081).
- Click OK.
- In the HTTP Listener configuration screen, click the Responses tab.
- In the Response section, set the desired values for Body and Status code.
- In the Error Response section, set the desired values for Body and Status code.
Add Validation Element:-
- Use the “Is Number” validation element to check if the request is a number.
- If the request is an integer, then and only then it will pass to the next element. Otherwise, it will go to the error handling block.
- Use the “value” attribute to specify the query parameter to be validated.
- Set the “queryParams” attribute to “customerid”.
- Use the “numberType” attribute to define the type of number validation.
- Configure number type as integer we are applying validation rules.
- Set “numberType” to “integer” to apply the validation rule.
By using value as attributes.queryParams.customerid
Add the Database Connector to Your Project:-
- In the Mule Palette view, click on Search in Exchange.
- Search for “Database Connector” and select it.
- Drag and drop the “Select” connector as we want to retrieve the records from PostgreSQL.
Add PostgreSQL Connector Dependency:-
- In your Mule Canvas, navigate to the database connector and configuration with the PostgreSQL Database, by clicking on the {+} icon.
- Add the PostgreSQL Connector (Maven) dependency by adding JDBC Driver:
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.2</version>
</dependency>
Configure Database Connection:-
- Enter the necessary connection details like:-
- URL ⇒ jdbc:postgresql://178.18.16.208:5432/mulesoft_db
- Driver Class Name ⇒ org.postgresql.Driver
- User ⇒ As per Requirement
- Passwords ⇒ As per Requirement
Test the Connection:-
- Run your application in Anypoint Studio to test the MySQL connection.
- Verify that you can connect to the MySQL database and perform operations successfully.
- By using the input parameters as a customer_Id: attributes.queryParams.customerid we are passing the request body value to the SQL query.
Transform Database data into JSON :-
- In the Mule Palette view, select “Transform Message (Core)” as the process.
- Drag it onto the Studio canvas.
- “Transform Message (Core)” to transform the data
Using Script:-
%dw 2.0
output application/json
---
{
"customer_id" : payload[0].'customer_id',
"customer_name" : payload[0].'customer_name',
"customer_status" : payload[0].'customer_status',
"customer_address" : payload[0].'customer_address', }
Add Logger Component to Your Flow & Configure the Logger:-
- The Logger component helps monitor and debug your Mule application by logging important information like error messages, status notifications, payloads, etc.
- Specify the message you want to log by setting the “message” attribute in the Logger configuration. eg, here we are giving passing message attribute with #[pauload] to log the data so that we can see data or errors can be shown in the console.
- So that whatever the payload might be it will be sent back to the source Listener.
Now we handle error if the request we receive is not in Integer Format:-
- In the Mule Palette view, select “On Error Propagate” as the Error Handling Block.
- Drag it onto the Studio canvas.
- Set the Type of error as VALIDATION:INVALID_NUMBER
- If the request body which is sent is not in Integer, then it will be sent to the Error handling block and there, we have added On Error Propagate block so that whenever it catches a certain element which we had selected it will send back the error in the form of description back to the source.
- For sending that error response we had configured a Transform Message element so it will compile the error and status code in JSON form.
%dw 2.0
output application/json
---
{
"status": 400,
"message" : error.description}
Note:- Order of the placement of the Error blocks is very important cause it will determine which block should get executed first and last by sequence.
Code for the configuration- pom.xml (please adjust some part from this snippet based on your needs)
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:db="http://www.mulesoft.org/schema/mule/db"
xmlns:validation="http://www.mulesoft.org/schema/mule/validation"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/validation http://www.mulesoft.org/schema/mule/validation/current/mule-validation.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="268ac32e-878a-4c4c-b706-e3be6a836098" >
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<db:config name="Database_Config" doc:name="Database Config" doc:id="fae30b55-a96a-4a9d-b2f1-069378b2470a" >
<db:generic-connection url="jdbc:postgresql://173.17.18.205:5432/mulesoft_db" driverClassName="org.postgresql.Driver" user="postgres" password="postgres" />
</db:config>
<flow name="poc_error_handlingFlow" doc:id="fb4ec22a-dedd-491e-9828-f726f2c11079" >
<http:listener doc:name="Listener" doc:id="251147af-e992-4d46-92eb-80a875de34dc" config-ref="HTTP_Listener_config" path="fetch-customerorder">
<http:error-response statusCode="#[vars.statusCode]" reasonPhrase="#[vars.reasonPhrase]" >
<http:body ><![CDATA[#[payload]]]></http:body>
</http:error-response>
</http:listener>
<validation:is-number numberType="INTEGER" doc:name="Is number" doc:id="a430e130-8f0a-4129-84f4-5752a5472b82" value="#[attributes.queryParams.customerid]" message="customer id should be number"/>
<db:select doc:name="Select_Customer_order" doc:id="c7168bec-9fc6-40fb-8415-2eeaff64b0eb" config-ref="Database_Config">
<db:sql><![CDATA[SELECT * FROM public.customer_order WHERE customer_id = :customer_Id]]></db:sql>
<db:input-parameters><![CDATA[#[{
customer_Id: attributes.queryParams.customerid
}]]]></db:input-parameters>
</db:select>
<ee:transform doc:name="Transform Message" doc:id="cf347ee1-e890-4456-a856-756956bc9708" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
"customer_id" : payload[0].'customer_id',
"customer_name" : payload[0].'customer_name',
"customer_status" : payload[0].'customer_status',
"customer_address" : payload[0].'customer_address',
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<logger level="INFO" doc:name="Logger" doc:id="8e1f4b3f-af23-4cf7-ae3a-890481409ebc" message="#[payload[0]]"/>
<error-handler >
<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate" doc:id="d1036d7b-42f4-4651-8244-dc69c5778aa8" type="VALIDATION:INVALID_NUMBER">
<ee:transform doc:name="Transform Message" doc:id="50f72687-53c7-4482-aedd-2355baea2a55" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
"status": 400,
"message" : error.description
}]]></ee:set-payload>
</ee:message>
<ee:variables >
<ee:set-variable variableName="statusCode" ><![CDATA[400]]></ee:set-variable>
<ee:set-variable variableName="reasonPhrase" ><![CDATA["Bad Request, I think"]]></ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate All Exceptions" doc:id="593dbae2-f626-457b-9c9e-9adc92fe4f37" type="ANY">
<ee:transform doc:name="Transform Message" doc:id="77fbe1e8-1a1a-42fd-b7fe-6df0ac699db9" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
"status": 500,
"message" : "Internal error"
}]]></ee:set-payload>
</ee:message>
<ee:variables >
<ee:set-variable variableName="statusCode" ><![CDATA[500]]></ee:set-variable>
<ee:set-variable variableName="reasonPhrase" ><![CDATA["Internal Server Error"]]></ee:set-variable>
</ee:variables>
</ee:transform>
</on-error-propagate>
</error-handler>
</flow>
</mule>
2. A Mule Flow to handle the error with the function of “On Error Continue” block allows the program to bypass errors and proceed with subsequent operations without being halted by the encountered error.
Create a Mule Project:-
- Create a Mule Project:In Anypoint Studio, go to File > New > Mule Project.
- Enter a name for your project and click Finish.
Configure a Source:-
- In the Mule Palette view, select “HTTP Listener” as the source.
- Drag it onto the Studio canvas.
- Set Path to the desired path for the listener.
- Click the plus sign (+) next to the Connector configuration field to configure a global element that can be used by all.
- Set Host to the desired host (e.g., 0.0.0.0).
- Set Port to the desired port (e.g., 8081).
- Click OK.
- In the HTTP Listener configuration screen, click the Responses tab.
- In the Response section, set the desired values for Body and Status code.
- In the Error Response section, set the desired values for Body and Status code.
Add Validation Element:-
- Use the “Is Number” validation element to check if the request is a number.
- If the request is an integer, then and only then it will pass to the next element. Otherwise, it will go to the error handling block.
- Use the “value” attribute to specify the query parameter to be validated.
- Set the “queryParams” attribute to “customerid”.
- Use the “numberType” attribute to define the type of number validation.
- Configure number type as integer we are applying validation rules.
- Set “numberType” to “integer” to apply the validation rule.
By using value as attributes.queryParams.customerid
Add Try Block to the flow:-
- If an exception occurs within the Try block, it will be caught and processed accordingly.
- Configure the Try block to gracefully handle errors and continue execution.
Add the Database Connector in Try Block:-
- In the Mule Palette view, click on Search in Exchange.
- Search for “Database Connector” and select it.
- Drag and drop the “Select” connector as we want to retrieve the records from PostgreSQL.
Add PostgreSQL Connector Dependency:-
- In your Mule Canvas, navigate to the database connector and configuration with the PostgreSQL Database, by clicking on the {+} icon.
- Add the PostgreSQL Connector(Maven) dependency by adding JDBC Driver:
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.2</version>
</dependency>
Configure Database Connection:-
- Enter the necessary connection details like:-
- URL ⇒ jdbc:postgresql://178.18.16.208:5432/mulesoft_db
- Driver Class Name ⇒ org.postgresql.Driver
- User ⇒ As per Requirement
- Passwords ⇒ As per Requirement
Test the Connection:-
- Run your application in Anypoint Studio to test the MySQL connection.
- Verify that you can connect to the MySQL database and perform operations successfully.
- By using the input parameters as a customer_Id: attributes.queryParams.customerid we are passing the request body value to the SQL query.
Now We handle error if the request we receive is not in Integer Format:-
- In the Mule Palette view, select “On Error Continue” as the Error Handling Block.
- Drag it onto the Studio canvas.
- Set the Type of error as Any
- If there is any error while we are retrieving data from the Database then the flow will create an exemption for a specific Try block and continue to execute the flow.
Transform Database data into JSON :-
- In the Mule Palette view, select “Transform Message (Core)” as the process.
- Drag it onto the Studio canvas.
- “Transform Message (Core)” to transform the data
Using Script:-
%dw 2.0
output application/json
---
{
"customer_id" : payload[0].'customer_id',
"customer_name" : payload[0].'customer_name',
"customer_status" : payload[0].'customer_status',
"customer_address" : payload[0].'customer_address', }
Add Logger Component to Your Flow & Configure the Logger: -
- The Logger component helps monitor and debug your Mule application by logging important information like error messages, status notifications, payloads, etc.
- Specify the message you want to log by setting the “message” attribute in the Logger configuration. E.g. here we are giving passing message attribute with #[pauload] to log the data so that we can see data or errors can be shown in the console.
- So that whatever the payload might be it will be sent back to the source Listener.
Note:- Difference between “On Error Propagate” and “On Error Continue” is that “On Error Propagate” the block sends the response of the error back to the source.
While “On Error Continue” block ignores the error happening and pushes the process ahead so that error does not block further happening operations.
Result: -
Code for the configuration- pom.xml (please adjust some part from this snippet based on your needs)
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:db="http://www.mulesoft.org/schema/mule/db"
xmlns:validation="http://www.mulesoft.org/schema/mule/validation"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/validation http://www.mulesoft.org/schema/mule/validation/current/mule-validation.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="49375c18-b095-471e-a9e0-2cdf535a3a28" >
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<db:config name="Database_Config" doc:name="Database Config" doc:id="a015a96b-dfe4-4be1-8813-7f50c0aa0dc5" >
<db:generic-connection url="jdbc:postgresql://172.16.16.203:5432/mulesoft_db" driverClassName="org.postgresql.Driver" user="postgres" password="postgres" />
</db:config>
<validation:config name="Validation_Config" doc:name="Validation Config" doc:id="139c2567-39a3-41a0-b845-9b3f2e5e9fb0" />
<flow name="poc_error_handling_secondFlow" doc:id="0fdfb973-c9c0-464e-81b7-6676fe457f2d" >
<http:listener doc:name="Listener" doc:id="c2cc6368-ccad-4136-aa34-a17218a34741" config-ref="HTTP_Listener_config" path="fetch-customerorder">
<http:error-response statusCode="#[vars.statusCode]" reasonPhrase="#[vars.reasonPhrase]">
<http:body ><![CDATA[#[payload]]]></http:body>
</http:error-response>
</http:listener>
<validation:is-number numberType="INTEGER" doc:name="Is number" doc:id="7f62067c-145b-400c-906f-46626ca576c5" value="#[attributes.queryParams.customerid]" message="customer id should be number" config-ref="Validation_Config"/>
<logger level="INFO" doc:name="Logger" doc:id="f6fb358e-e02c-4f73-9bf7-6f0dd7dff052" message="#[attributes.queryParams.customerid]"/>
<try doc:name="Try" doc:id="de1a346e-9157-4180-a9a6-9498409ee376" >
<db:select doc:name="Select_Customer_order" doc:id="51b597e8-cd50-44e0-8960-687add512831" config-ref="Database_Config">
<db:sql><![CDATA[SELECT * FROM public.customer_order WHERE customer_id = :customer_Id]]></db:sql>
<db:input-parameters><![CDATA[#[{
customer_Id: attributes.queryParams.customerid
}]]]></db:input-parameters>
</db:select>
<error-handler >
<on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" doc:id="2d352817-b3de-43a5-8e3d-4631ed524b95" type="ANY">
<logger level="INFO" doc:name="Logger" doc:id="59f8b285-9f73-49dc-b39d-64a184ae1b9d" message="database error occured on the error continue"/>
</on-error-continue>
</error-handler>
</try>
<ee:transform doc:name="Transform Message" doc:id="3fc5fe14-b885-4e67-aa09-226ad864eea3" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
"customer_id" : payload[0].'customer_id',
"customer_name" : payload[0].'customer_name',
"customer_status" : payload[0].'customer_status',
"customer_address" : payload[0].'customer_address',
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<logger level="INFO" doc:name="Logger" doc:id="925c3b05-bae3-4854-9caa-e5072b26fa45" message="#[payload[0]]" />
</flow>
</mule>
3. Saving the Logs in the file so for further monitoring through AnyPoint Studio:-
Path where logs are saved :\AnypointStudio\plugins\org.mule.tooling.server.4.5.ee_7.16.0.202311061606\mule\logs
Coming Up Next….
This continuation blog post marks the continuing of an exciting journey, introducing Part 5 of our MuleSoft base knowledge series and offering a tantalizing glimpse into the captivating content awaiting readers in future installments. Stay tuned for a wealth of engaging topics and insightful discussions on MuleSoft in the upcoming blogs!
- MuleSoft Integration Platform Basics: “Empowering Connectivity: API Gateway Setup and Database Invoicing with Fast API Integration and Real-Time Project Monitoring on CloudHub” — Part 6
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
- Access Part I of the series “A Catalyst for Seamless Integration and Business Transformation” — here
- Access Part 2 of the series “Streamlining Data Integration: A Guide to Setting up Connectors and Network Sharing” — here
- Access Part 3 of the series MuleSoft Integration Platform Basics: “Efficient Data Processing — here
- Access Part 4 of the series MuleSoft Integration Platform Basics: Optimizing Workflows — here
Follow us & Connect at:-
LinkedIn:- https://in.linkedin.com/company/thinqloud
medium.com:- Thinqloud Solutions — Medium
Company Site:- https://www.thinqloud.com/
Please let us know if you have any suggestions, comments or just general feedback for us!