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  
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.isEmpty()? null: exceptions.get(exceptions.size() - 1).t);
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 }