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 RetriesExhaustedException(final String msg)37 public RetriesExhaustedException(final String msg) { 38 super(msg); 39 } 40 RetriesExhaustedException(final String msg, final IOException e)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 ThrowableWithExtraContext(final Throwable t, final long when, final String extras)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 toString()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 */ RetriesExhaustedException(final String callableVitals, int numTries, List<Throwable> exceptions)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 RetriesExhaustedException(final int numTries, final List<ThrowableWithExtraContext> exceptions)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 getMessage(String callableVitals, int numTries, List<Throwable> exceptions)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 getMessage(final int numTries, final List<ThrowableWithExtraContext> exceptions)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 } 117