Blog top image

Exception handling in Spring Boot


কখন চেক এবং আনচেক এক্সেপশন 

কখন চেক এবং আনচেক ব্যবহার করবো এর কোন ধরা বাধা নিয়ম নাই। অনেকটাই ব্যক্তিগত পছন্দ। নিচে আমার পছন্দ তুলে ধরলাম


কখন চেক ব্যবহার করবো?

  • আমি জানি কোডের এই জায়গায় সমস্যা হতে পারে। যেমন কেউ ফাইল পড়তে চেষ্টা করল কিন্তু ফাইল অন্য কেউ ডিলিট করে দিয়েছে।
  • কোডের ক্রিটিক্যাল জায়গা। যেমন ব্যবহারকারী গুরুত্বপূর্ণ তথ্য পরিবর্তন করার কোড
  • লাইব্রেরি বানালে, লাইব্রেরী যে ব্যবহার করবে তাকে এরর হ্যান্ডল করতে বাধ্য করা জন্য চেক এক্সসেপশন


কখন আনচেক ব্যবহার করবো?

উপরে কারন গুলা ছাড়া বাকি সব জায়গায় আনচেক ব্যবহার করা যায়। কারণ, অনেক বেশি ট্রাই কেচ কোডকে পড়তে কঠিন করে তুলে। আর অনেক বেশি লাইন লিখতে হয়।


কাস্টম এক্সসেপশন

জাভাতে Exception ক্লাস হলো চেক এক্সসেপ্সন এর মূল ক্লাস আর RuntimeException ক্লাস হল আনচেক এক্সসেপশন এর মূল ক্লাস। এদেরকে সরাসরি ব্যবহার করে এক্সসেপশন থ্রো করা যায়। কিন্তু সবচেয়ে ভালো হয় এক্সসেপশন এর ধরণ বুঝে কাস্টম এক্সসেপশন ক্লাস বানানো। কাস্টম এক্সসেপশন সবচেয়ে বড় সুবিধা হলো ইচ্ছে মতো ফিল্ড যুক্ত করা যায়। কথার কথা আপনি বিভিন্ন ল্যাঙ্গুয়েজে এক্সসেপশন থ্রো করতে চান।


কাস্টম আনচেক এক্সসেপশন ক্লাস

@Data
@AllArgsConstructor
public class MyCustomException extends RuntimeException {
  private final String message;
}


কাস্টম এক্সসেপশন ব্যবহার করা

 if (something-wrong) {
	throw new MyCustomException("Something wrong");
}



স্প্রিং বুটে এক্সসেপশন হ্যান্ডলিং

স্প্রিং বুটে এক্সসেপশন হলে তাকে API আকারে রেস্পন্স পাঠানো যায় এবং এতো সব কাজ করার জন্য গ্লোবালি একটা RestControllerAdvice ক্লাস লিখতেই হয়।আসলে জীবন স্প্রিং বুট এর আগে কখনোই এত সহজ ছিল না। নিচে কন্ট্রোলার এডভাইস দিয়ে কিভাবে রেস্ট এর রেস্পন্স আকারে এক্সসেপশন থ্রো করা যায় সেটা দেখাবো।


প্রথমে একটা এরর ক্লাস লিখে ফেলি। সেটা হবে আমাদের রেস্পন্স।

@Getter
@Builder
@AllArgsConstructor
public class ErrorResponse {

  private Integer status;

  private String message;

  private List<String> errors;
}


দরকার অনুযায়ীকাস্টম এক্সসেপশন

@Setter
@Getter
@AllArgsConstructor
public class GeoIpFetchException extends RuntimeException {
  private final String message;
}


@Data
@AllArgsConstructor
public class GeoIpLookUpException extends RuntimeException {
  private final String message;
}


এখন একটা কন্ট্রোলার এডভাইস লিখলেই স্প্রিং বুটে কাজ শেষ

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;


import java.util.Date;


@RestControllerAdvice
public class RestExceptionHandler {

    @ExceptionHandler(GeoIpFetchException.class)
    public final ResponseEntity< ErrorResponse > handleGeoDbFetchException(GeoIpFetchException ex, WebRequest request) {
        ApiError apiError = ErrorResponse.builder()
                .status(404)                 .message("Something wrong with GeoIP fetch")                 .errors(Collections.singletonList(ex.getMessage()))                 .build();         return new ResponseEntity<>(apiError, HttpStatus.INTERNAL_SERVER_ERROR);     }     @ExceptionHandler(GeoIpLookUpException.class)     public final ResponseEntity<ErrorResponse> handleGeoIpLookUpException(GeoIpLookUpException ex, WebRequest request) {
        ApiError apiError = ErrorResponse.builder()
                .status(503)
                .message("Something wrong with GeoIP Lookup")                 .errors(Collections.singletonList(ex.getMessage()))
                .build();         return new ResponseEntity<>(apiError, HttpStatus.INTERNAL_SERVER_ERROR);     } }



কাস্টম এক্সসেপশন থ্রো করলে অটোমেটিক তা জেসন আকারে API এর রেস্পন্স হয়ে যাবে।

catch (Exception e) {
   log.error(e.getMessage(), e);
   throw new GeoIpLookUpException("Something wrong while looking up the geo region");
}