Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ Refactor : refactoring errorCode by domain #415

Merged
merged 3 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/streetdrop-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ test {
tasks.named('test') {
useJUnitPlatform()
finalizedBy jacocoTestReport
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.depromeet.common.error;

import com.depromeet.common.error.dto.ErrorCode;
import com.depromeet.common.error.dto.ErrorResponseDto;
import com.depromeet.common.error.exception.common.BusinessException;
import com.depromeet.common.error.exception.common.NotFoundException;
import com.depromeet.common.error.handler.ErrorEvent;
import com.depromeet.common.error.dto.CommonErrorCode;
import com.depromeet.common.error.event.ErrorEvent;
import com.depromeet.common.error.exception.internal.BusinessException;
import com.depromeet.common.error.exception.internal.NotFoundException;
import com.depromeet.common.error.http.dto.HttpErrorResponseDto;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -15,6 +15,7 @@
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpClientErrorException;

import java.sql.SQLException;

Expand All @@ -25,70 +26,60 @@ public class GlobalExceptionHandler {

private final ApplicationEventPublisher eventPublisher;

@ExceptionHandler(HttpClientErrorException.Forbidden.class)
protected ResponseEntity<HttpErrorResponseDto> handleForbiddenException(
final HttpClientErrorException.Forbidden e,
final HttpServletRequest request
) {
return HttpErrorResponseDto.toResponseEntity(CommonErrorCode.FORBIDDEN);
}

@ExceptionHandler(BusinessException.class)
protected ResponseEntity<ErrorResponseDto> handleBusinessException(
protected ResponseEntity<HttpErrorResponseDto> handleBusinessException(
final BusinessException e,
final HttpServletRequest request
) {
log.error("BusinessException: {} {}", e.getErrorCode(), request.getRequestURL());
return ResponseEntity
.status(e.getErrorCode().getStatus().value())
.body(new ErrorResponseDto(e.getErrorCode()));
return HttpErrorResponseDto.toResponseEntity(e.getErrorCode());
}

@ExceptionHandler(NotFoundException.class)
protected ResponseEntity<ErrorResponseDto> handleNotFoundException(
final NotFoundException e,
final HttpServletRequest request) {

log.error("MemberNotFoundException: {} {}", e.getErrorCode(), request.getRequestURL());
return ResponseEntity
.status(e.getErrorCode().getStatus().value())
.body(new ErrorResponseDto(e.getErrorCode()));
protected ResponseEntity<HttpErrorResponseDto> handleNotFoundException(
final NotFoundException e
) {
return HttpErrorResponseDto.toResponseEntity(e.getErrorCode());
}

@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponseDto> handleMethodArgumentNotValidException(
protected ResponseEntity<HttpErrorResponseDto> handleMethodArgumentNotValidException(
final MethodArgumentNotValidException e,
final HttpServletRequest request
) {
log.error("MethodArgumentNotValidException: {} {}", e.getMessage(), request.getRequestURL());
ErrorResponseDto errorResponseDto = ErrorResponseDto.builder()
.code(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getCode())
.status(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getStatus().value())
.error(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getStatus().name())
HttpErrorResponseDto httpErrorResponseDto = HttpErrorResponseDto.builder()
.errorResponseCode(CommonErrorCode.METHOD_ARGUMENT_NOT_VALID.getErrorResponseCode())
.status(CommonErrorCode.METHOD_ARGUMENT_NOT_VALID.getStatus().value())
.title(CommonErrorCode.METHOD_ARGUMENT_NOT_VALID.getTitle())
.message(e.getAllErrors().get(0).getDefaultMessage()).build();

return ResponseEntity
.status(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getStatus().value())
.body(errorResponseDto);
.status(CommonErrorCode.METHOD_ARGUMENT_NOT_VALID.getStatus().value())
.body(httpErrorResponseDto);
}

@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
protected ResponseEntity<ErrorResponseDto> handleMethodNotSupportException(
final HttpRequestMethodNotSupportedException e
) {
ErrorResponseDto errorResponseDto = ErrorResponseDto.builder()
.code(ErrorCode.METHOD_NOT_ALLOWED.getCode())
.status(ErrorCode.METHOD_NOT_ALLOWED.getStatus().value())
.error(ErrorCode.METHOD_NOT_ALLOWED.getStatus().name())
.message(e.getMessage()).build();

return ResponseEntity
.status(ErrorCode.METHOD_NOT_ALLOWED.getStatus().value())
.body(errorResponseDto);
protected ResponseEntity<HttpErrorResponseDto> handleMethodNotSupportException() {
return HttpErrorResponseDto.toResponseEntity(CommonErrorCode.METHOD_NOT_ALLOWED);
}

@ExceptionHandler(value = {Exception.class, RuntimeException.class, SQLException.class, DataIntegrityViolationException.class})
protected ResponseEntity<ErrorResponseDto> handleInternalException(
protected ResponseEntity<HttpErrorResponseDto> handleInternalException(
final Exception e,
final HttpServletRequest request
) {
log.error("Exception: {} {}", e.getMessage(), request.getRequestURL());
eventPublisher.publishEvent(new ErrorEvent(ErrorCode.INTERNAL_SERVER_ERROR, request, e));
return ResponseEntity
.status(ErrorCode.INTERNAL_SERVER_ERROR.getStatus().value())
.body(new ErrorResponseDto(ErrorCode.INTERNAL_SERVER_ERROR));
eventPublisher.publishEvent(new ErrorEvent<>(CommonErrorCode.INTERNAL_SERVER_ERROR, request, e));
return HttpErrorResponseDto.toResponseEntity(CommonErrorCode.INTERNAL_SERVER_ERROR);
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.depromeet.common.error.dto;

import com.depromeet.common.error.dto.interfaces.ErrorCode;
import com.depromeet.common.error.dto.interfaces.ErrorCodeInterface;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum CommonErrorCode implements ErrorCodeInterface {
/*
* Basic Client Error
*/
BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON_BAD_REQUEST", "Bad Request", "The request could not be understood or was missing required parameters."),
METHOD_ARGUMENT_NOT_VALID(HttpStatus.BAD_REQUEST, "COMMON_METHOD_ARGUMENT_NOT_VALID", "Method Argument Not Valid", "One or more method arguments are not valid."),
UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "COMMON_UNAUTHORIZED", "Unauthenticated", "Authentication is required and has failed or has not been provided."),
FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON_FORBIDDEN", "Forbidden", "Access to the requested resource is forbidden."),
NOT_FOUND(HttpStatus.NOT_FOUND, "COMMON_NOT_FOUND", "Not Found", "The requested resource could not be found."),
METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "COMMON_METHOD_NOT_ALLOWED", "Method Not Allowed", "The method received in the request-line is known by the origin server but not supported."),
CONFLICT(HttpStatus.CONFLICT, "COMMON_CONFLICT", "Conflict", "The request could not be completed due to a conflict with the current state of the target resource."),

/*
* StreetDrop Common Error
*/
CANNOT_USE_BANNED_WORD(HttpStatus.BAD_REQUEST, "COMMON_CAN_NOT_USE_BANNED_WORD", "Can Not Use Banned Word", "Cannot Use Banned Word"),

/*
* Basic Server Error
*/
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON_INTERNAL_SERVER_ERROR", "Internal Server Error", "An unexpected error occurred"),
NOT_IMPLEMENTED(HttpStatus.NOT_IMPLEMENTED, "COMMON_NOT_IMPLEMENTED", "Not Implemented", "The server does not support the functionality required to fulfill the request.");


private final HttpStatus status;
private final String errorResponseCode;
private final String title;
private final String message;

@Override
public ErrorCode toErrorCode() {
return ErrorCode
.builder()
.status(status)
.errorResponseCode(errorResponseCode)
.title(title)
.message(message)
.build();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.depromeet.common.error.dto;

import com.depromeet.common.error.dto.interfaces.ErrorCode;

import java.util.Optional;

public class ErrorCodeMapper {
public static Optional<ErrorCode> findByErrorCode(String code) {
for (ErrorCode errorCode : ErrorCode.values()) {
if (errorCode.getCode().equals(code)) {
return Optional.of(errorCode);
}
}
return Optional.empty();
var result = StreetDropErrorCodeList.getInstance().getStreetDropErrorCodeList();
return result.stream().filter(streetDropErrorCode -> streetDropErrorCode.getErrorResponseCode().equals(code))
.findFirst().map(StreetDropErrorCode::getErrorCode);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.depromeet.common.error.dto;

import com.depromeet.common.error.dto.interfaces.ErrorCode;
import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class StreetDropErrorCode {

private String errorResponseCode;

private ErrorCode errorCode;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.depromeet.common.error.dto;

import com.depromeet.common.error.dto.interfaces.ErrorCode;
import com.depromeet.common.error.dto.interfaces.ErrorCodeInterface;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.TypeFilter;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Getter
@Slf4j
public class StreetDropErrorCodeList {

private static volatile StreetDropErrorCodeList instance;
private final List<StreetDropErrorCode> streetDropErrorCodeList;

private StreetDropErrorCodeList() {
streetDropErrorCodeList = createStreetDropErrorCodeList();
}

public static StreetDropErrorCodeList getInstance(){
if (instance == null) {
synchronized (StreetDropErrorCodeList.class) {
if (instance == null) {
instance = new StreetDropErrorCodeList();
}
}
}
return instance;
}

private synchronized List<StreetDropErrorCode> createStreetDropErrorCodeList() {
List<StreetDropErrorCode> streetDropErrorCodeList = new ArrayList<>();

try {
ClassPathScanningCandidateComponentProvider s = new ClassPathScanningCandidateComponentProvider(false);

TypeFilter tf = new AssignableTypeFilter(ErrorCodeInterface.class);
s.addIncludeFilter(tf);

Set<BeanDefinition> components = s.findCandidateComponents("com.depromeet");

for (BeanDefinition component : components) {
Class<?> className = Class.forName(component.getBeanClassName());

if (className.isEnum()) {
for (var errorCode : className.getEnumConstants()) {
if (errorCode != null) {
String errorResponseCode = (String) errorCode.getClass().getMethod("getErrorResponseCode").invoke(errorCode);
ErrorCode error = (ErrorCode) errorCode.getClass().getMethod("toErrorCode").invoke(errorCode);
var streetDropError = new StreetDropErrorCode(errorResponseCode, error);
streetDropErrorCodeList.add(streetDropError);
}
}
}
}

} catch (Exception ignored) {
}

return streetDropErrorCodeList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.depromeet.common.error.dto.interfaces;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
@Builder
public class ErrorCode implements ErrorCodeInterface {
private HttpStatus status;
private String errorResponseCode;
private String title;
private String message;

@Override
public ErrorCode toErrorCode() {
return this;
}

public void appendMessage(String additionalMessage) {
this.message += " " + additionalMessage;
}

}
Loading
Loading