View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF 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.apache.hadoop.hbase.client;
20  
21  import java.io.IOException;
22  import java.util.Date;
23  import java.util.List;
24  
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.classification.InterfaceStability;
27  
28  /**
29   * Exception thrown by HTable methods when an attempt to do something (like
30   * commit changes) fails after a bunch of retries.
31   */
32  @InterfaceAudience.Public
33  @InterfaceStability.Stable
34  public class RetriesExhaustedException extends IOException {
35    private static final long serialVersionUID = 1876775844L;
36  
37    public RetriesExhaustedException(final String msg) {
38      super(msg);
39    }
40  
41    public RetriesExhaustedException(final String msg, final IOException e) {
42      super(msg, e);
43    }
44  
45    /**
46     * Datastructure that allows adding more info around Throwable incident.
47     */
48    @InterfaceAudience.Private
49    public static class ThrowableWithExtraContext {
50      private final Throwable t;
51      private final long when;
52      private final String extras;
53  
54      public ThrowableWithExtraContext(final Throwable t, final long when,
55          final String extras) {
56        this.t = t;
57        this.when = when;
58        this.extras = extras;
59      }
60  
61      @Override
62      public String toString() {
63        return new Date(this.when).toString() + ", " + extras + ", " + t.toString();
64      }
65    }
66  
67    /**
68     * Create a new RetriesExhaustedException from the list of prior failures.
69     * @param callableVitals Details from the Callable we were using
70     * when we got this exception.
71     * @param numTries The number of tries we made
72     * @param exceptions List of exceptions that failed before giving up
73     */
74    public RetriesExhaustedException(final String callableVitals, int numTries,
75        List<Throwable> exceptions) {
76      super(getMessage(callableVitals, numTries, exceptions));
77    }
78  
79    /**
80     * Create a new RetriesExhaustedException from the list of prior failures.
81     * @param numTries
82     * @param exceptions List of exceptions that failed before giving up
83     */
84    @InterfaceAudience.Private
85    public RetriesExhaustedException(final int numTries,
86                                     final List<ThrowableWithExtraContext> exceptions) {
87      super(getMessage(numTries, exceptions),
88          (exceptions != null && !exceptions.isEmpty() ?
89              exceptions.get(exceptions.size() - 1).t : null));
90    }
91  
92    private static String getMessage(String callableVitals, int numTries,
93        List<Throwable> exceptions) {
94      StringBuilder buffer = new StringBuilder("Failed contacting ");
95      buffer.append(callableVitals);
96      buffer.append(" after ");
97      buffer.append(numTries + 1);
98      buffer.append(" attempts.\nExceptions:\n");
99      for (Throwable t : exceptions) {
100       buffer.append(t.toString());
101       buffer.append("\n");
102     }
103     return buffer.toString();
104   }
105 
106   private static String getMessage(final int numTries,
107       final List<ThrowableWithExtraContext> exceptions) {
108     StringBuilder buffer = new StringBuilder("Failed after attempts=");
109     buffer.append(numTries + 1);
110     buffer.append(", exceptions:\n");
111     for (ThrowableWithExtraContext t : exceptions) {
112       buffer.append(t.toString());
113       buffer.append("\n");
114     }
115     return buffer.toString();
116   }
117 }