<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bishwa Poudel</title>
    <description>The latest articles on DEV Community by Bishwa Poudel (@bishwapoudel).</description>
    <link>https://dev.to/bishwapoudel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F535883%2Fa3f3199d-3b77-42f5-bdb7-ef18ff28d09e.jpg</url>
      <title>DEV Community: Bishwa Poudel</title>
      <link>https://dev.to/bishwapoudel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bishwapoudel"/>
    <language>en</language>
    <item>
      <title>Advanced Error Handling in Spring Boot Microservices</title>
      <dc:creator>Bishwa Poudel</dc:creator>
      <pubDate>Mon, 28 Oct 2024 06:54:06 +0000</pubDate>
      <link>https://dev.to/bishwapoudel/advanced-error-handling-in-spring-boot-microservices-3ca3</link>
      <guid>https://dev.to/bishwapoudel/advanced-error-handling-in-spring-boot-microservices-3ca3</guid>
      <description>&lt;p&gt;In complex microservices, advanced error handling goes beyond simple exception logging. Effective error handling is crucial for reliability, scalability, and maintaining good user experience. This article will cover advanced techniques for error handling in Spring Boot microservices, focusing on strategies for managing errors in distributed systems, handling retries, creating custom error responses, and logging errors in a way that facilitates debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Basic Error Handling in Spring Boot&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s start with a foundational error handling approach in Spring Boot to set up a baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1.1 Using &lt;code&gt;@ControllerAdvice&lt;/code&gt; and &lt;code&gt;@ExceptionHandler&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Spring Boot provides a global exception handler with &lt;code&gt;@ControllerAdvice&lt;/code&gt; and &lt;code&gt;@ExceptionHandler&lt;/code&gt;. This setup lets us handle exceptions across all controllers in one place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity&amp;lt;ErrorResponse&amp;gt; handleResourceNotFound(ResourceNotFoundException ex) {
        ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
        return new ResponseEntity&amp;lt;&amp;gt;(error, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity&amp;lt;ErrorResponse&amp;gt; handleGeneralException(Exception ex) {
        ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred.");
        return new ResponseEntity&amp;lt;&amp;gt;(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;ErrorResponse&lt;/code&gt; is a custom error model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ErrorResponse {
    private String code;
    private String message;

    // Constructors, Getters, and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;1.2 Returning Consistent Error Responses&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ensuring all exceptions return a consistent error response format (e.g., &lt;code&gt;ErrorResponse&lt;/code&gt;) helps clients interpret errors correctly.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2. Advanced Techniques for Error Handling&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2.1 Centralized Logging and Tracking with Error IDs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Assigning a unique error ID to each exception helps track specific errors across services. This ID can also be logged alongside exception details for easier debugging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ExceptionHandler(Exception.class)
public ResponseEntity&amp;lt;ErrorResponse&amp;gt; handleGeneralException(Exception ex) {
    String errorId = UUID.randomUUID().toString();
    log.error("Error ID: {}, Message: {}", errorId, ex.getMessage(), ex);

    ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", 
                                             "An unexpected error occurred. Reference ID: " + errorId);
    return new ResponseEntity&amp;lt;&amp;gt;(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clients receive an error response containing errorId, which they can report back to support, linking them directly to the detailed logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2.2 Adding Retry Logic for Transient Errors&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In distributed systems, transient issues (like network timeouts) can be resolved with a retry. Use Spring’s @Retryable for retry logic on service methods.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Setup&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;First, add Spring Retry dependency in your pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.retry&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-retry&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, enable Spring Retry with &lt;code&gt;@EnableRetry&lt;/code&gt; and annotate methods that need retries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableRetry
@Service
public class ExternalService {

    @Retryable(
        value = { ResourceAccessException.class },
        maxAttempts = 3,
        backoff = @Backoff(delay = 2000))
    public String callExternalService() throws ResourceAccessException {
        // Code that calls an external service
    }

    @Recover
    public String recover(ResourceAccessException e) {
        log.error("External service call failed after retries.", e);
        return "Fallback response due to error.";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration retries the method up to 3 times, with a delay of 2 seconds between attempts. If all attempts fail, the recover method executes as a fallback.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2.3 Using Feign Client with Fallback in Microservices&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For error handling in service-to-service calls, Feign provides a declarative way to set up retries and fallbacks.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Feign Configuration&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Define a Feign client with fallback support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@FeignClient(name = "inventory-service", fallback = InventoryServiceFallback.class)
public interface InventoryServiceClient {
    @GetMapping("/api/inventory/{id}")
    InventoryResponse getInventory(@PathVariable("id") Long id);
}

@Component
public class InventoryServiceFallback implements InventoryServiceClient {

    @Override
    public InventoryResponse getInventory(Long id) {
        // Fallback logic, like returning cached data or an error response
        return new InventoryResponse(id, "N/A", "Fallback inventory");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach ensures that if &lt;code&gt;inventory-service&lt;/code&gt; is unavailable, the &lt;code&gt;InventoryServiceFallback&lt;/code&gt; kicks in with a predefined response.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3. Error Logging and Observability&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.1 Centralized Logging with ELK Stack&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Configure an ELK (Elasticsearch, Logstash, Kibana) stack to consolidate logs from multiple microservices. With a centralized logging system, you can easily trace issues across services and view logs with associated error IDs.&lt;/p&gt;

&lt;p&gt;For example, configure log patterns in application.yml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Adding Trace IDs with Spring Cloud Sleuth
&lt;/h3&gt;

&lt;p&gt;In distributed systems, tracing a single transaction across multiple services is critical. Spring Cloud Sleuth provides distributed tracing with unique trace and span IDs.&lt;/p&gt;

&lt;p&gt;Add Spring Cloud Sleuth in your dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-cloud-starter-sleuth&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;4. Custom Error Handling for REST APIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.1 Creating Custom Exception Classes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Define custom exceptions to provide more specific error handling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class InvalidRequestException extends RuntimeException {
    public InvalidRequestException(String message) {
        super(message);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4.2 Custom Error Response Structure&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Customize error responses by implementing &lt;code&gt;ErrorAttributes&lt;/code&gt; for structured and enriched error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map&amp;lt;String, Object&amp;gt; getErrorAttributes(
            WebRequest webRequest, ErrorAttributeOptions options) {
        Map&amp;lt;String, Object&amp;gt; errorAttributes = super.getErrorAttributes(webRequest, options);
        errorAttributes.put("timestamp", LocalDateTime.now());
        errorAttributes.put("customMessage", "An unexpected error occurred");
        return errorAttributes;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register &lt;code&gt;CustomErrorAttributes&lt;/code&gt; in your configuration to automatically customize all error responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4.3 API Error Response Standardization with Problem Details (RFC 7807)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Use the Problem Details format for a standardized API error structure. Define an error response model based on RFC 7807:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ProblemDetailResponse {
    private String type;
    private String title;
    private int status;
    private String detail;
    private String instance;

    // Constructors, Getters, and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, return this structured response from the @ControllerAdvice methods to maintain a consistent error structure across all APIs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ExceptionHandler(InvalidRequestException.class)
public ResponseEntity&amp;lt;ProblemDetailResponse&amp;gt; handleInvalidRequest(InvalidRequestException ex) {
    ProblemDetailResponse error = new ProblemDetailResponse(
        "https://example.com/errors/invalid-request",
        "Invalid Request",
        HttpStatus.BAD_REQUEST.value(),
        ex.getMessage(),
        UUID.randomUUID().toString()
    );
    return new ResponseEntity&amp;lt;&amp;gt;(error, HttpStatus.BAD_REQUEST);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;5. Circuit Breakers for Resilience&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Integrating a circuit breaker pattern protects your microservice from repeatedly calling a failing service.&lt;/p&gt;

&lt;p&gt;Using Resilience4j Circuit Breaker&lt;br&gt;
Add Resilience4j to your dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.resilience4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;resilience4j-spring-boot2&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, wrap a method with a circuit breaker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@CircuitBreaker(name = "inventoryService", fallbackMethod = "inventoryFallback")
public InventoryResponse getInventory(Long id) {
    // Call to external service
}

public InventoryResponse inventoryFallback(Long id, Throwable ex) {
    log.warn("Fallback due to error: {}", ex.getMessage());
    return new InventoryResponse(id, "N/A", "Fallback inventory");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup stops calling &lt;code&gt;getInventory&lt;/code&gt; if it fails multiple times, and &lt;code&gt;inventoryFallback&lt;/code&gt; returns a safe response instead.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Advanced error handling in Spring Boot microservices includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Centralized error handling&lt;/strong&gt; for consistent responses and simplified debugging.&lt;br&gt;
&lt;strong&gt;Retries and circuit breakers&lt;/strong&gt; for resilient service-to-service calls.&lt;br&gt;
&lt;strong&gt;Centralized logging and traceability&lt;/strong&gt; with tools like ELK and Sleuth.&lt;br&gt;
&lt;strong&gt;Custom error formats&lt;/strong&gt; with Problem Details and structured error responses.&lt;br&gt;
These techniques help ensure your microservices are robust, providing consistent, traceable error responses while preventing cascading failures across services.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>microservices</category>
      <category>programming</category>
    </item>
    <item>
      <title>How I fixed java.io.IOException: Broken Pipe in Java (Wildfly 10.1)</title>
      <dc:creator>Bishwa Poudel</dc:creator>
      <pubDate>Fri, 08 Jan 2021 00:56:19 +0000</pubDate>
      <link>https://dev.to/bishwapoudel/how-i-fixed-java-io-ioexception-broken-pipe-in-java-wildfly-10-1-86k</link>
      <guid>https://dev.to/bishwapoudel/how-i-fixed-java-io-ioexception-broken-pipe-in-java-wildfly-10-1-86k</guid>
      <description>&lt;h3&gt;
  
  
  Preview
&lt;/h3&gt;

&lt;p&gt;My first path crossed with Broken Pipe issue was when I was gazing at the logs of a software I was working on.  &lt;/p&gt;

&lt;p&gt;The stack for the software was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaEE 7 with JAX-RS&lt;/li&gt;
&lt;li&gt;Java 8&lt;/li&gt;
&lt;li&gt;Wildfly 10.1 as application server&lt;/li&gt;
&lt;li&gt;Nginx was used as reverse proxy and load balancer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could see following traces flooding the log:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java.lang.RuntimeException: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I have ignored it a couple of times previously, thinking it hasn't created any havoc in the production server and wasn't quite sure how it was generated and how to handle, or completely prevent it.&lt;/p&gt;
&lt;h3&gt;
  
  
  What exactly is Broken Pipe?
&lt;/h3&gt;

&lt;p&gt;In simple term, Broken Pipe means that a machine is attempting to read or write data from/to a pipe, while the machine on other end of the pipe has died or been terminated. Now, since the connection is closed, new connection should be established for further transfer of data, or else the data transfer ceases.&lt;/p&gt;
&lt;h3&gt;
  
  
  How does it occur?
&lt;/h3&gt;

&lt;p&gt;One of the most common cause for this issue is when a client closes an open connection while performing any action (like loading a page, or downloading an attachment). It also happens when forcefully closing certain connections when using a proxy/load balancer like Nginx (like closing the web browser or even simply cancelling a download) or when the connection is slow. &lt;/p&gt;

&lt;p&gt;A simple scenario: a browser requesting resource from server, and in response server returns response to browser. What if user closes the browser when server was sending response to browser? The connection between server to browser gets closed unexpectedly. This then gives rise to Broken Pipe and the exception is termed as java.io.IOException: Broken Pipe in Java. &lt;/p&gt;

&lt;p&gt;This can happen as well with anything that is interrupting a connection between the client and server including performance issues or even having network intermittency. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not every Broken Pipe exception is developer's fault&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Possible factors giving rise to this exception:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Number of end users&lt;br&gt;
As one of the major cause of Broken Pipe is the behavior of user (unexpectedly closing active browser session before server could complete sending response), increase in number of end user increases chance of having Broken Pipe.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Heavy response load&lt;br&gt;
Heavy response from server takes significant amount of time to get transferred to client side, and this huge time span can be the case for Broken Pipe.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Timeout of server&lt;br&gt;
If the web server couldn't get the response from service in certain time which is equal to timeout value set in server, it closes connection to the client end returning 503: Gateway Timeout and consequently giving rise to Broken Pipe.  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Is Broken Pipe Exception a Red Signal?
&lt;/h3&gt;

&lt;p&gt;Well to be fair, it isn't a red signal, because largely it is caused by normal behavior of user, and there are always a chance of services being shutdown due to some failures. But, if a server is running on relatively large number of user requests at a time, then not only Broken Pipe, but any exception seems to pose a problem. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In my case, due to the high network traffic, logs were flooded with broken pipe exception. As, writing to a file (I/O operation) is one of the expensive operation performed by server, imagine server being flooded with Broken Pipe related exception, and the amount of resource server has to put in order to write that exception stacktrace to log file. This had caused server to response slowly and had made it sluggish.&lt;br&gt;&lt;br&gt;
At this point, I realized, &lt;strong&gt;YES BROKEN PIPE EXCEPTION IS A RED SIGNAL when scaled to large traffic.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Challenges on handling or removing Broken Pipe
&lt;/h3&gt;

&lt;p&gt;The system was using Wildfly 10.1 as application server, and was written on JavaEE 7. Handling this scenario wasn't a cakewalk for me as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Replicating this exception in local or QA environment requires all planets to be aligned properly ( just kidding ), but yes it's toooo tough.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling exception in Java is easy, as long as the exception is caught inside catch block. The nature of Unhandled exception: java.io.IOException: Broken pipe is such that, it is raised from Wildfly container and gets logged out in stacktrace instead of being trapped in catch block. Now, imagine having to deal with exception that cannot be caught from code. Gosh!!!!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will never know, which request raised the issue, as, the server was getting high amount of requests, any of them could have been the cause of exception. Adding logs to every rest endpoints along with socket endpoints is not feasible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Fixing java.io.IOException : Broken Pipe
&lt;/h3&gt;

&lt;p&gt;Finally, after so much of out of context talk, here comes the main section (hope its worth the wait).  &lt;/p&gt;

&lt;p&gt;Two ways to remove exception from the system are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Investigate the root cause of the exception, and eliminate it.&lt;/li&gt;
&lt;li&gt;Handle the exception gracefully, with proper logging or some action.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Eliminating root causes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Asking user not to close connection unexpectedly&lt;/strong&gt;&lt;br&gt;
This is impossible to do, for god's sake  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reducing api response load&lt;/strong&gt;&lt;br&gt;
This is somehow achievable, but in a legacy system, operating on large amount of data, rewriting all the logic so that api responses aren't heavy is also not feasible in all case.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increasing Timeout of Server&lt;/strong&gt;&lt;br&gt;
Nginx has a variable named &lt;em&gt;proxy_read_timeout&lt;/em&gt; which has default value of 60s, increasing this value will also minimize the chances of Broken Pipe.  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even after eliminating exact root cause, which itself is hard to detect in this case, we can't completely rule out the existence of Broken Pipe. Can we? &lt;/p&gt;

&lt;p&gt;Hence, next solution is to handle Broken Pipe gracefully.&lt;/p&gt;
&lt;h3&gt;
  
  
  Handling java.io.IOException: Broken Pipe
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Suppress the log from logger itself&lt;/strong&gt;
If you use log4j as log manager, adding following configuration to log4j.properties will help to get rid of exception flooding the logs due to Broken Pipe.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log4j.logger.org.apache.catalina.connector.ClientAbortException = ERROR, console, cloudAppender
log4j.additivity.org.apache.catalina.connector.ClientAbortException = false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upgrading Resteasy within Wildfly&lt;/strong&gt;
We were using Resteasy implementation of JAX-RS for implementing REST in Java, and Resteasy v3.0.19 is bundled with Wildfly 10.1. With hope of finding some fixes in the resteasy itself, I started to dig into release notes of Resteasy and found out that after Resteasy-Client v3.1.1, Unhandled Exception: java.io.IOException can be caught from code, unlike container exposing it directly onto logtrace.
Hence, upgrading version of Resteasy Client allows us to handle exception through Global Exception Handler (described in later point).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Steps to upgrade Resteasy within Wildfly&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Find location of Resteasy distribution jars:&lt;br&gt;
The location of Resteasy distribution jars lies inside:&lt;br&gt;
&lt;em&gt;WILDFLY_HOME/modules/system/layers/base/org/jboss/resteasy/resteasy-jaxrs/main&lt;/em&gt;&lt;br&gt;
and the file name is: &lt;em&gt;resteasy-jaxrs-3.0.19.Final.jar&lt;/em&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the zip file of target version of resteasy (3.1.1 and above) from &lt;a href="http://resteasy.jboss.org/downloads"&gt;Resteasy downloads&lt;/a&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unpack the file in temporary directory. It has two other zip files within it:&lt;br&gt;
&lt;em&gt;resteasy-jboss-modules-3.1.1.Final-mavenized.zip&lt;/em&gt; &amp;amp;&lt;br&gt;
&lt;em&gt;resteasy-jboss-modules-3.1.1.Final.zip&lt;/em&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unpack both .zip files at:  &lt;br&gt;
&lt;em&gt;WILDFLY_HOME/modules/system/layers/base&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update resteasy dependencies' version in &lt;em&gt;pom.xml&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt; 
  &amp;lt;groupId&amp;gt;org.jboss.resteasy&amp;lt;/groupId&amp;gt; 
  &amp;lt;artifactId&amp;gt;resteasy-jaxrs&amp;lt;/artifactId&amp;gt; 
  &amp;lt;version&amp;gt;3.1.1.Final&amp;lt;/version&amp;gt;
  &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Global Exception Handler&lt;/strong&gt;
I further added Generic Exception Mapper from the java code itself, to catch and handle the Broken Pipe. &lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  My final approach
&lt;/h3&gt;

&lt;p&gt;Though I had gathered multiple techniques to solve the issue, following are the things I actually implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upgrade Wildfly to v11.0, as it automatically comes with Resteasy v3.1.1 (the version that I exactly wanted) bundled within it.&lt;/li&gt;
&lt;li&gt;Handle exception through Global Exception Handler &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and with this, the issue of Broken Pipe now only exists in old logs archives 😎😎. &lt;/p&gt;

&lt;h3&gt;
  
  
  Parting words
&lt;/h3&gt;

&lt;p&gt;It's my first blog, yeah it's a bit long, but I was giving insights into how I actually approached the issue and fixed it. Feel free to provide feedback in the comment section &amp;amp;  watch this space for more development blogs in future.&lt;/p&gt;

&lt;p&gt;Also, a bit of self promotion at the end 😉. Reach out to me at  &lt;a href="https://twitter.com/_bishwapoudel"&gt;Twitter&lt;/a&gt; &amp;amp; &lt;a href="https://www.linkedin.com/in/bishwapoudel/"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://issues.redhat.com/browse/RESTEASY-1238"&gt;RESTEASY-1238&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/treasure-data/digdag/issues/756"&gt;Github Issue - 756&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/resteasy/Resteasy/pull/1169"&gt;Github - 1169&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/treasure-data/digdag/pull/772"&gt;Github - 772&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://mtyurt.net/post/spring-how-to-handle-ioexception-broken-pipe.html"&gt;Blog post&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://jira.atlassian.com/browse/JRASERVER-63503"&gt;Jira - Atlassian&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
