Skip to content

Commit

Permalink
feat : Add exception handling(#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
pbg0205 committed Jun 22, 2021
1 parent d97f420 commit 5695fbd
Show file tree
Hide file tree
Showing 21 changed files with 192 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.codesquad.issuetracker.exception.BadRequestException;
import com.codesquad.issuetracker.user.domain.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -46,13 +48,17 @@ public String getJwt(User user) {
}

public User getUserFromJwt(String token) {
DecodedJWT jwt = jwtVerifier.verify(token);
return User.instanceOf(
UUID.fromString(jwt.getClaim(ID).asString()),
jwt.getClaim(NICKNAME).asString(),
jwt.getClaim(IMAGE_URL).asString(),
jwt.getClaim(GITHUB_ID).asString(),
jwt.getClaim(APPLE_ID).asString()
);
try {
DecodedJWT jwt = jwtVerifier.verify(token);
return User.instanceOf(
UUID.fromString(jwt.getClaim(ID).asString()),
jwt.getClaim(NICKNAME).asString(),
jwt.getClaim(IMAGE_URL).asString(),
jwt.getClaim(GITHUB_ID).asString(),
jwt.getClaim(APPLE_ID).asString()
);
} catch (JWTVerificationException jwtVerificationException) {
throw new BadRequestException("토큰 확인이 필요합니다.");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.codesquad.issuetracker.auth.interceptor;

import com.codesquad.issuetracker.auth.component.JwtUtils;
import com.codesquad.issuetracker.exception.BadTokenRequestException;
import com.codesquad.issuetracker.exception.UnauthorizedException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

Expand Down Expand Up @@ -31,11 +33,11 @@ private String getJwt(HttpServletRequest request) {
String authorizationHeader = request.getHeader("Authorization");

if (authorizationHeader == null) {
throw new RuntimeException("토큰 없음");
throw new UnauthorizedException("토큰이 존재하지 않습니다.");
}

if (!authorizationHeader.startsWith("Bearer")) {
throw new RuntimeException("토큰 타입 이상");
throw new BadTokenRequestException("토큰 타입 올바르지 않습니다.");
}

return authorizationHeader.replaceFirst("Bearer", "").trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.codesquad.issuetracker.auth.dto.AccessTokenResponse;
import com.codesquad.issuetracker.auth.dto.GitHubUser;
import com.codesquad.issuetracker.auth.dto.JwtResponse;
import com.codesquad.issuetracker.exception.BadRequestException;
import com.codesquad.issuetracker.user.domain.User;
import com.codesquad.issuetracker.user.infra.UserRepository;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -47,10 +48,10 @@ public GithubLoginService(GitHubOauthWebValues gitHubOauthWebValues,
public JwtResponse issueToken(String code, GitHubOauthValues gitHubOauthValues) {
RestTemplate request = new RestTemplate();
AccessTokenResponse accessToken = getAccessToken(code, gitHubOauthValues, request)
.orElseThrow(() -> new RuntimeException("요청 바디 없음"));
.orElseThrow(() -> new BadRequestException("access token을 발급받지 못했습니다."));

GitHubUser githubUser = getUserFromOauth(accessToken, request)
.orElseThrow(() -> new RuntimeException("요청 바디 없음"));
.orElseThrow(() -> new BadRequestException("github user를 받지 못했습니다."));

User user = userRepository.findByGitHubId(githubUser.getLogin())
.orElseGet(() -> userRepository.save(User.fromGitHubUser(githubUser)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.codesquad.issuetracker.comment.dto.CommentResponse;
import com.codesquad.issuetracker.comment.dto.CommentWrapper;
import com.codesquad.issuetracker.comment.infra.CommentRepository;
import com.codesquad.issuetracker.exception.CommentNotFoundException;
import com.codesquad.issuetracker.exception.NotFoundException;
import com.codesquad.issuetracker.user.domain.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -34,7 +36,7 @@ public CommentWrapper createComment(CommentRequest commentRequest, User author)
@Transactional
public CommentWrapper updateComment(CommentRequest commentRequest, UUID id) {
Comment comment = commentRepository.findById(id)
.orElseThrow(RuntimeException::new);
.orElseThrow(CommentNotFoundException::new);
comment.updateContent(commentRequest);
return CommentWrapper.wrap(CommentResponse.fromEntity(comment));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.codesquad.issuetracker.exception;

import org.springframework.http.HttpStatus;

public class BadRequestException extends HttpException {
public BadRequestException(String message) {
super(HttpStatus.BAD_REQUEST, message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.codesquad.issuetracker.exception;

import org.springframework.http.HttpStatus;

public class BadTokenRequestException extends HttpException {
public BadTokenRequestException(String message) {
super(HttpStatus.BAD_REQUEST, message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codesquad.issuetracker.exception;

public class CommentNotFoundException extends NotFoundException {
public CommentNotFoundException() {
super("comment가 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.codesquad.issuetracker.exception;

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

@Getter
public class HttpException extends RuntimeException{

private final HttpStatus httpStatus;

public HttpException(HttpStatus httpStatus, String message) {
super(message);
this.httpStatus = httpStatus;
}

public HttpException(HttpStatus httpStatus, String message, Throwable cause) {
super(message, cause);
this.httpStatus = httpStatus;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.codesquad.issuetracker.exception;

import com.codesquad.issuetracker.exception.dto.HttpExceptionResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class HttpExceptionHandler {

@ExceptionHandler(HttpException.class)
public ResponseEntity<HttpExceptionResponse> handle(HttpException httpException) {
return new ResponseEntity<HttpExceptionResponse>(
HttpExceptionResponse.of(httpException.getMessage()),
httpException.getHttpStatus()
);
}

@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public HttpExceptionResponse handleIllegalArgumentException(IllegalArgumentException illegalArgumentException){
return HttpExceptionResponse.of(illegalArgumentException.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codesquad.issuetracker.exception;

public class IssueNotFoundException extends NotFoundException {
public IssueNotFoundException() {
super("이슈가 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codesquad.issuetracker.exception;

public class LabelNotFoundException extends NotFoundException {
public LabelNotFoundException() {
super("라벨이 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codesquad.issuetracker.exception;

public class MilestoneNotFoundException extends NotFoundException {
public MilestoneNotFoundException() {
super("마일스톤이 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.codesquad.issuetracker.exception;

import org.springframework.http.HttpStatus;

public class NotFoundException extends HttpException{
public NotFoundException(String message) {
super(HttpStatus.NOT_FOUND, message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.codesquad.issuetracker.exception;

import org.springframework.http.HttpStatus;

public class S3UploadFailException extends HttpException {
public S3UploadFailException(String message, Throwable cause) {
super(HttpStatus.INTERNAL_SERVER_ERROR, message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.codesquad.issuetracker.exception;

import org.springframework.http.HttpStatus;

public class UnauthorizedException extends HttpException {
public UnauthorizedException(String message) {
super(HttpStatus.UNAUTHORIZED, message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codesquad.issuetracker.exception;

public class UserNotFoundException extends NotFoundException {
public UserNotFoundException() {
super("유저가 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.codesquad.issuetracker.exception.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class HttpExceptionResponse {
private final String message;

public static HttpExceptionResponse of(String message) {
return new HttpExceptionResponse(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.codesquad.issuetracker.image.component;

import com.codesquad.issuetracker.exception.S3UploadFailException;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
Expand Down Expand Up @@ -30,7 +31,7 @@ public String upload(MultipartFile multipartFile) {
s3.putObject(putObjectRequest, RequestBody.fromInputStream(multipartFile.getInputStream(), multipartFile.getSize()));

} catch (IOException ioException) {
throw new RuntimeException("Image Upload Error", ioException);
throw new S3UploadFailException("이미지 업로드를 실패했습니다.", ioException);
}

return bucketUrl + objectKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.codesquad.issuetracker.comment.domain.Comment;
import com.codesquad.issuetracker.comment.infra.CommentRepository;
import com.codesquad.issuetracker.exception.*;
import com.codesquad.issuetracker.issue.domain.Issue;
import com.codesquad.issuetracker.issue.dto.*;
import com.codesquad.issuetracker.issue.infra.IssueRepository;
Expand Down Expand Up @@ -45,16 +46,18 @@ public IssueWrapper createIssue(IssueCreateRequest issueCreateRequest, User auth
Issue issue = issueCreateRequest.createIssue(author);

for (UUID assigneeId : issueCreateRequest.getAssigneeIds()) {
issue.addAssignee(userRepository.findById(assigneeId).orElseThrow(RuntimeException::new));
issue.addAssignee(userRepository.findById(assigneeId)
.orElseThrow(UserNotFoundException::new));
}

for (UUID labelId : issueCreateRequest.getLabelIds()) {
issue.addLabel(labelRepository.findById(labelId).orElseThrow(RuntimeException::new));
issue.addLabel(labelRepository.findById(labelId)
.orElseThrow(LabelNotFoundException::new));
}

if (issueCreateRequest.hasMilestoneId()) {
issue.setMilestone(milestoneRepository.findById(issueCreateRequest.getMilestoneId())
.orElseThrow(RuntimeException::new));
.orElseThrow(MilestoneNotFoundException::new));
}

issue = issueRepository.save(issue);
Expand All @@ -65,58 +68,59 @@ public IssueWrapper createIssue(IssueCreateRequest issueCreateRequest, User auth
}

public IssueWrapper readIssueById(Long id) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
List<Comment> comments = commentRepository.findAllByIssueId(id);
return IssueWrapper.wrap(IssueResponse.fromEntity(issue, comments));
}

@Transactional
public IssueWrapper updateIssue (IssueRequest issueRequest, Long id) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
List<Comment> comments = commentRepository.findAllByIssueId(id);
issue.updateIssue(issueRequest);
return IssueWrapper.wrap(IssueResponse.fromEntity(issue, comments));
}

@Transactional
public void addLabel(Long id, LabelIdRequest labelIdRequest) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
Label label = labelRepository.findById(labelIdRequest.getLabelId()).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
Label label = labelRepository.findById(labelIdRequest.getLabelId()).orElseThrow(LabelNotFoundException::new);
issue.addLabel(label);
}

@Transactional
public void removeLabel(Long id, UUID labelId) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
Label label = labelRepository.findById(labelId).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
Label label = labelRepository.findById(labelId).orElseThrow(LabelNotFoundException::new);
issue.removeLabel(label);
}

@Transactional
public void addAssignee(Long id, AssigneeIdRequest assigneeIdRequest) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
User assignee = userRepository.findById(assigneeIdRequest.getAssigneeId()).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
User assignee = userRepository.findById(assigneeIdRequest.getAssigneeId())
.orElseThrow(UserNotFoundException::new);
issue.addAssignee(assignee);
}

@Transactional
public void removeAssignee(Long id, UUID assigneeId) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
User assignee = userRepository.findById(assigneeId).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
User assignee = userRepository.findById(assigneeId).orElseThrow(UserNotFoundException::new);
issue.removeAssignee(assignee);
}

@Transactional
public void setMilestone(Long id, MilestoneIdRequest milestoneIdRequest) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
Milestone milestone = milestoneRepository.findById(milestoneIdRequest.getMilestoneId())
.orElseThrow(RuntimeException::new);
.orElseThrow(MilestoneNotFoundException::new);
issue.setMilestone(milestone);
}

@Transactional
public void removeMilestone(Long id) {
Issue issue = issueRepository.findById(id).orElseThrow(RuntimeException::new);
Issue issue = issueRepository.findById(id).orElseThrow(IssueNotFoundException::new);
issue.removeMilestone();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.codesquad.issuetracker.label.service;

import com.codesquad.issuetracker.exception.LabelNotFoundException;
import com.codesquad.issuetracker.label.domain.Label;
import com.codesquad.issuetracker.label.dto.LabelDto;
import com.codesquad.issuetracker.label.dto.LabelRequestDto;
Expand Down Expand Up @@ -34,17 +35,15 @@ public LabelWrapper createLabels(LabelRequestDto newLabel) {
@Transactional
public LabelWrapper updateLabel(UUID id, LabelRequestDto updatingLabelInfo) {
Label updatingLabel = labelRepository.findById(id)
//TODO: Exception
.orElseThrow(() -> new RuntimeException("Not Found"));
.orElseThrow(LabelNotFoundException::new);
updatingLabel.update(updatingLabelInfo.toEntity());

return LabelWrapper.wrap(LabelDto.fromEntity(updatingLabel));
}

public void deleteLabel(UUID id) {
Label deletingLabel = labelRepository.findById(id)
//TODO: Exception
.orElseThrow(() -> new RuntimeException("Not Found"));
.orElseThrow(LabelNotFoundException::new);
labelRepository.delete(deletingLabel);
}
}
Loading

0 comments on commit 5695fbd

Please sign in to comment.