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 org.apache.hadoop.hbase.classification.InterfaceAudience;
22  import org.apache.hadoop.hbase.classification.InterfaceStability;
23  
24  import java.io.IOException;
25  import java.util.Date;
26  import java.util.List;
27  import java.util.concurrent.Callable;
28  
29  /**
30   * Exception thrown by HTable methods when an attempt to do something (like
31   * commit changes) fails after a bunch of retries.
32   */
33  @InterfaceAudience.Public
34  @InterfaceStability.Stable
35  public class RetriesExhaustedException extends IOException {
36    private static final long serialVersionUID = 1876775844L;
37  
38    public RetriesExhaustedException(final String msg) {
39      super(msg);
40    }
41  
42    public RetriesExhaustedException(final String msg, final IOException e) {
43      super(msg, e);
44    }
45  
46    /**
47     * Datastructure that allows adding more info around Throwable incident.
48     */
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    public RetriesExhaustedException(final int numTries,
85                                     final List<ThrowableWithExtraContext> exceptions) {
86      super(getMessage(numTries, exceptions),
87          (exceptions != null && !exceptions.isEmpty() ?
88              exceptions.get(exceptions.size() - 1).t : null));
89    }
90  
91    private static String getMessage(String callableVitals, int numTries,
92        List<Throwable> exceptions) {
93      StringBuilder buffer = new StringBuilder("Failed contacting ");
94      buffer.append(callableVitals);
95      buffer.append(" after ");
96      buffer.append(numTries + 1);
97      buffer.append(" attempts.\nExceptions:\n");
98      for (Throwable t : exceptions) {
99        buffer.append(t.toString());
100       buffer.append("\n");
101     }
102     return buffer.toString();
103   }
104 
105   private static String getMessage(final int numTries,
106       final List<ThrowableWithExtraContext> exceptions) {
107     StringBuilder buffer = new StringBuilder("Failed after attempts=");
108     buffer.append(numTries + 1);
109     buffer.append(", exceptions:\n");
110     for (ThrowableWithExtraContext t : exceptions) {
111       buffer.append(t.toString());
112       buffer.append("\n");
113     }
114     return buffer.toString();
115   }
116 }