<?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: Pablo Mora</title>
    <description>The latest articles on DEV Community by Pablo Mora (@pablo_mora_9e40570a97f54e).</description>
    <link>https://dev.to/pablo_mora_9e40570a97f54e</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2131206%2Fe3edf248-705f-406b-980a-596dc72421fc.png</url>
      <title>DEV Community: Pablo Mora</title>
      <link>https://dev.to/pablo_mora_9e40570a97f54e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pablo_mora_9e40570a97f54e"/>
    <language>en</language>
    <item>
      <title>Basic Exception Handling in Java Spring</title>
      <dc:creator>Pablo Mora</dc:creator>
      <pubDate>Sun, 03 Aug 2025 19:02:49 +0000</pubDate>
      <link>https://dev.to/pablo_mora_9e40570a97f54e/basic-exception-handling-in-java-spring-56h4</link>
      <guid>https://dev.to/pablo_mora_9e40570a97f54e/basic-exception-handling-in-java-spring-56h4</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this post, we’re going to talk about what exceptions are and how to handle errors in a Java project using &lt;code&gt;@ControllerAdvice&lt;/code&gt;. We’ll go over creating custom exceptions and sending back the right HTTP status codes. By the end, your API will be easier to maintain, more reliable, and give your users clearer error messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an exception?
&lt;/h2&gt;

&lt;p&gt;Let’s start with the basics: what’s an exception?&lt;br&gt;
An exception is basically Java’s way of saying, “Hey, something went wrong!” and it stops the normal happy flow of your program.&lt;br&gt;
It usually occurs when something unexpected happens, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trying to access a file that doesn’t exist.&lt;/li&gt;
&lt;li&gt;Dividing by zero.&lt;/li&gt;
&lt;li&gt;Our always friend, NullPointerException.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an exception occurs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java creates an exception object with details about the error.&lt;/li&gt;
&lt;li&gt;The regular flow of the application stops.&lt;/li&gt;
&lt;li&gt;Java tries to find a matching handler to deal with the exception.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Types of exceptions
&lt;/h2&gt;

&lt;p&gt;There are two main types of exceptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Checked exceptions → Must be either caught or declared (e.g., IOException).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unchecked exceptions (Runtime exceptions) → Don’t require explicit handling, often indicate programming errors (e.g., NullPointerException).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In REST APIs, unchecked exceptions are the most common. Without proper handling, they return 500 Internal Server Error with a raw stack trace—which is not user-friend which is what we will try to improve later in this article.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Should we Handle Exceptions?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prevent internal errors from leaking stack traces to clients.&lt;/li&gt;
&lt;li&gt;Respond with meaningful HTTP status codes (404, 400, 500, etc.).&lt;/li&gt;
&lt;li&gt;Provide consistent and clear error messages.&lt;/li&gt;
&lt;li&gt;Centralize error handling.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Create custom exceptions
&lt;/h2&gt;

&lt;p&gt;A good practice in any project is to define your own exception classes for common business errors, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other examples of custom exceptions is &lt;code&gt;BadRequestException&lt;/code&gt;, &lt;code&gt;UnauthorizedException&lt;/code&gt;, etc&lt;/p&gt;

&lt;h2&gt;
  
  
  Use @ControllerAdvice for Global Exception Handling
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;@ControllerAdvice&lt;/code&gt; to define that this class will be the exception handler for the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ControllerAdvice&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GlobalExceptionHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleNotFound&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NOT_FOUND&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleGeneral&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// this will catch any exception extending from Excepcion.class&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"Internal server error"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Throw exceptions in your services or controllers
&lt;/h2&gt;

&lt;p&gt;Now that we've defined our custom exceptions, and the global exception handler then we can safely throw exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/items/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt; &lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;itemRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Item with ID "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" not found"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Client Response Examples
&lt;/h2&gt;

&lt;p&gt;With everything defined we will have nice and well understanding exceptions like the following.&lt;/p&gt;

&lt;p&gt;Resource Not Found&lt;/p&gt;

&lt;p&gt;When requesting a non-existent resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 404 Not Found
Body: "Item with ID 10 not found"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For internal errors (e.g., unhandled NullPointerException):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 500 Internal Server Error
Body: "Internal server error"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Handling exceptions centrally with &lt;code&gt;@ControllerAdvice&lt;/code&gt; and using custom exceptions helps you build clean, robust APIs. This improves the client experience and makes your code easier to maintain.&lt;/p&gt;

</description>
      <category>java</category>
      <category>backend</category>
      <category>spring</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
