1 | /** |
2 | * Licensed to jclouds, Inc. (jclouds) under one or more |
3 | * contributor license agreements. See the NOTICE file |
4 | * distributed with this work for additional information |
5 | * regarding copyright ownership. jclouds licenses this file |
6 | * to you under the Apache License, Version 2.0 (the |
7 | * "License"); you may not use this file except in compliance |
8 | * with the License. You may obtain a copy of the License at |
9 | * |
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * |
12 | * Unless required by applicable law or agreed to in writing, |
13 | * software distributed under the License is distributed on an |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
15 | * KIND, either express or implied. See the License for the |
16 | * specific language governing permissions and limitations |
17 | * under the License. |
18 | */ |
19 | package org.jclouds.util; |
20 | |
21 | import static com.google.common.base.Predicates.instanceOf; |
22 | import static com.google.common.base.Throwables.getCausalChain; |
23 | import static com.google.common.base.Throwables.propagate; |
24 | import static com.google.common.collect.Iterables.find; |
25 | |
26 | import java.util.NoSuchElementException; |
27 | |
28 | import org.jclouds.http.HttpResponseException; |
29 | import org.jclouds.rest.AuthorizationException; |
30 | import org.jclouds.rest.InsufficientResourcesException; |
31 | import org.jclouds.rest.ResourceNotFoundException; |
32 | |
33 | import com.google.common.base.Throwables; |
34 | import com.google.inject.ProvisionException; |
35 | import com.google.inject.spi.Message; |
36 | |
37 | /** |
38 | * General utilities used in jclouds code. |
39 | * |
40 | * @author Adrian Cole |
41 | */ |
42 | public class Throwables2 { |
43 | |
44 | @SuppressWarnings("unchecked") |
45 | public static <T extends Throwable> T getFirstThrowableOfType(Throwable from, Class<T> clazz) { |
46 | if (from instanceof ProvisionException) |
47 | return getFirstThrowableOfType(ProvisionException.class.cast(from), clazz); |
48 | try { |
49 | return (T) find(getCausalChain(from), instanceOf(clazz)); |
50 | } catch (NoSuchElementException e) { |
51 | return null; |
52 | } |
53 | } |
54 | |
55 | public static <T extends Throwable> T getFirstThrowableOfType(ProvisionException e, Class<T> clazz) { |
56 | for (Message message : e.getErrorMessages()) { |
57 | if (message.getCause() != null) { |
58 | T cause = getFirstThrowableOfType(message.getCause(), clazz); |
59 | if (cause instanceof ProvisionException) |
60 | return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz); |
61 | return cause; |
62 | } |
63 | } |
64 | return null; |
65 | } |
66 | |
67 | public static <T> T propagateOrNull(Exception from) { |
68 | propagate(from); |
69 | assert false : "exception should have propogated"; |
70 | return null; |
71 | } |
72 | |
73 | // Note this needs to be kept up-to-date with all top-level exceptions jclouds works against |
74 | @SuppressWarnings( { "unchecked", "rawtypes" }) |
75 | public static Exception returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(Class[] exceptionTypes, |
76 | Exception exception) throws Exception { |
77 | for (Class type : exceptionTypes) { |
78 | Throwable throwable = getFirstThrowableOfType(exception, type); |
79 | if (throwable != null) { |
80 | return (Exception) throwable; |
81 | } |
82 | } |
83 | for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class, |
84 | UnsupportedOperationException.class, IllegalArgumentException.class, AuthorizationException.class, |
85 | ResourceNotFoundException.class, InsufficientResourcesException.class, HttpResponseException.class }) { |
86 | Throwable throwable = getFirstThrowableOfType(exception, propagatableExceptionType); |
87 | if (throwable != null) { |
88 | throw (Exception) throwable; |
89 | } |
90 | } |
91 | Throwables.propagateIfPossible(exception.getCause(), Exception.class); |
92 | throw exception; |
93 | } |
94 | |
95 | public static <T> T propagateAuthorizationOrOriginalException(Exception e) { |
96 | AuthorizationException aex = getFirstThrowableOfType(e, AuthorizationException.class); |
97 | if (aex != null) |
98 | throw aex; |
99 | propagate(e); |
100 | assert false : "exception should have propogated " + e; |
101 | return null; |
102 | } |
103 | |
104 | } |