1 package cn.home1.oss.lib.errorhandle.internal;
2
3 import static cn.home1.oss.lib.errorhandle.api.ExceptionResolver.COMPOSITE_EXCEPTION_RESOLVER;
4
5 import com.google.common.collect.ImmutableMap;
6
7 import cn.home1.oss.lib.errorhandle.api.ExceptionResolver;
8 import cn.home1.oss.lib.errorhandle.api.ResolvedError;
9 import cn.home1.oss.lib.errorhandle.api.ResolvedErrorException;
10
11 import lombok.Setter;
12
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.beans.factory.annotation.Qualifier;
15 import org.springframework.boot.autoconfigure.web.ErrorAttributes;
16 import org.springframework.core.Ordered;
17 import org.springframework.core.annotation.Order;
18 import org.springframework.web.context.request.RequestAttributes;
19 import org.springframework.web.servlet.HandlerExceptionResolver;
20 import org.springframework.web.servlet.ModelAndView;
21
22 import java.util.Map;
23
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27
28
29
30
31
32
33
34 @Order(Ordered.HIGHEST_PRECEDENCE)
35 public class ExtendedErrorAttributes
36 implements ErrorAttributes, HandlerExceptionResolver, Ordered {
37
38 private static final String ERROR_ATTRIBUTE = ExtendedErrorAttributes.class.getName() + ".ERROR";
39
40 @Qualifier(COMPOSITE_EXCEPTION_RESOLVER)
41 @Autowired
42 @Setter
43 private ExceptionResolver<Throwable> resolver;
44
45 @Override
46 public Map<String, Object> getErrorAttributes(
47 final RequestAttributes requestAttributes,
48 final boolean includeStackTrace
49 ) {
50 final Throwable error = getError(requestAttributes);
51 final ResolvedError resolved = ResolvedErrorException.isResolvedError(error) ?
52 ((ResolvedErrorException) error).getError() :
53 this.resolver.resolve(requestAttributes, error);
54 return resolved != null ? resolved.toErrorAttributes() : ImmutableMap.of();
55 }
56
57 @Override
58 public int getOrder() {
59 return Ordered.HIGHEST_PRECEDENCE;
60 }
61
62 @Override
63 public ModelAndView resolveException(
64 final HttpServletRequest request,
65 final HttpServletResponse response,
66 final Object handler,
67 final Exception ex
68 ) {
69 final ResolvedError resolved = this.resolver.resolve(request, ex);
70 this.storeErrorAttributes(request, resolved != null ? new ResolvedErrorException(resolved) : ex);
71 return null;
72 }
73
74 private void storeErrorAttributes(final HttpServletRequest request, final Exception ex) {
75 request.setAttribute(ERROR_ATTRIBUTE, ex);
76 }
77
78 @Override
79 public Throwable getError(final RequestAttributes requestAttributes) {
80 final Throwable found = getAttribute(requestAttributes, ERROR_ATTRIBUTE);
81 return found != null ? found : getAttribute(requestAttributes, "javax.servlet.error.exception");
82 }
83
84 @SuppressWarnings("unchecked")
85 private <T> T getAttribute(final RequestAttributes requestAttributes, final String name) {
86 return (T) requestAttributes.getAttribute(name, RequestAttributes.SCOPE_REQUEST);
87 }
88 }