Basics of Error Handling

Sungju Kim·2024년 9월 5일

Sparta_Coding_Camp_TIL

목록 보기
31/53

For our project, we decided to use the GlobalExceptionController for our basic error handling.

GlobalExceptionController

package com.sparta.newsfeed.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.server.ResponseStatusException;

import javax.xml.crypto.Data;
import java.time.format.DateTimeParseException;
import java.util.Objects;

@RestControllerAdvice
public class GlobalExceptionController {

    // Password Not Found
    @ExceptionHandler(PasswordMismatchException.class)
    public ResponseEntity<String> passwordMismatchException(PasswordMismatchException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(HttpStatus.BAD_REQUEST + " :  " + ex.getMessage());
    }

    // Data Not Found
    @ExceptionHandler(DataNotFoundException.class)
    public ResponseEntity<String> dataNotFoundException(DataNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(HttpStatus.NOT_FOUND + " : " + ex.getMessage());
    }

    // Duplicated Data
    @ExceptionHandler(DataDuplicationException.class)
    public ResponseEntity<String> dataDuplicationException(DataDuplicationException ex) {
        return ResponseEntity.status(HttpStatus.CONFLICT).body(HttpStatus.CONFLICT + " : " + ex.getMessage());
    }

    // When method arguments with @Valid fails
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<String> validationExceptions(MethodArgumentNotValidException ex) {
        StringBuilder errorMessage = new StringBuilder();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String message = error.getDefaultMessage();
            errorMessage.append(fieldName).append(": ").append(message).append(". ");
        });
        return new ResponseEntity<>(errorMessage.toString(), HttpStatus.BAD_REQUEST);
    }


    //입력으로 다른 타입 입력했을 때 에러 (ex . @PathVariable 이 Long 타입인데 String 타입 입력했을때)
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public String idTypeMismatch(MethodArgumentTypeMismatchException ex) {
        return ex.getName() + " 의 입력된 값은 잘못된 입력 입니다. " +  Objects.requireNonNull(ex.getRequiredType()).getSimpleName() + " 타입으로 " + " 정확히 입력해주세요."
                + " 당신이 넣은 값은 " + ex.getValue() + " 입니다.";
    }
	
    // When a user tries to access methods beyond its authority
    @ExceptionHandler(ResponseStatusException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public String accessRights(ResponseStatusException ex) {
        return ex.getStatusCode() + ": " + ex.getReason() ;
    }
}

The very last one is what I made for cases where users attempt to modify or delete other people's posts or view inaccessible posts (posts by other uses whom are not their friend).

Example: viewing multiple posts

    @GetMapping("/posts")
    public Page<PageResponseDto> getPosts(@Auth AuthUser authUser,
                                          @RequestParam("feedUserEmail") String feedUserEmail,
                                          @RequestParam(value = "page", defaultValue = "1") int page,
                                          @RequestParam(value = "size", defaultValue = "10") int size) {

        // Check if the posts belongs to you or your friends
        boolean isOwner = Objects.equals(authUser.getEmail(), feedUserEmail);
        boolean isFriend = relationshipService.checkFriend(authUser.getEmail(), feedUserEmail);

        if (isOwner || isFriend) {
            return postService.getPosts(feedUserEmail, page-1, size);
        } else {
            throw new ResponseStatusException(HttpStatus.FORBIDDEN, "This is a private account. Try sending a friend request!");
        }
    }
profile
Fully ✨committed✨ developer, always eager to learn!

0개의 댓글