com.twitter.finagle.Exceptions.scala Maven / Gradle / Ivy
The newest version!
package com.twitter.finagle
import com.twitter.util.Duration
import java.net.SocketAddress
trait SourcedException extends Exception {
var serviceName: String = "unspecified"
}
trait NoStacktrace extends Exception {
override def fillInStackTrace = this
// specs expects non-empty stacktrace array
this.setStackTrace(NoStacktrace.NoStacktraceArray)
}
object NoStacktrace {
val NoStacktraceArray = Array(new StackTraceElement("com.twitter.finagle", "NoStacktrace", null, -1))
}
/** Request failures (eg. for request behavior changing brokers.) */
class RequestException(cause: Throwable) extends Exception(cause) with NoStacktrace with SourcedException {
def this() = this(null)
override def getStackTrace = if (cause != null) cause.getStackTrace else super.getStackTrace
}
trait TimeoutException extends SourcedException { self: Exception =>
protected val timeout: Duration
protected def explanation: String
override def getMessage = "exceeded %s to %s while %s".format(timeout, serviceName, explanation)
}
class RequestTimeoutException(
protected val timeout: Duration,
protected val explanation: String
) extends RequestException with TimeoutException
class IndividualRequestTimeoutException(timeout: Duration)
extends RequestTimeoutException(
timeout,
"waiting for a response for an individual request, excluding retries")
class GlobalRequestTimeoutException(timeout: Duration)
extends RequestTimeoutException(
timeout,
"waiting for a response for the request, including retries (if applicable)")
class NoBrokersAvailableException(
val name: String = "unknown"
) extends RequestException {
override def getMessage = "No hosts are available for " + name
}
class RetryFailureException(cause: Throwable) extends RequestException(cause)
/**
* Cancellation is propagated between a Finagle server and client intra-process
* when the server is interrupted by an upstream service. In cases like these, the pending Future
* is interrupted with this exception. The client will cancel its pending request which
* will propagate an interrupt to its downstream, and so on. This is done to conserve resources.
*/
class CancelledRequestException(cause: Throwable) extends RequestException(cause) {
def this() = this(null)
override def getMessage = {
if (cause == null)
"request cancelled"
else
"request cancelled due to " + cause
}
}
class TooManyWaitersException extends RequestException
/**
* A Future is satisfied with this exception when the process of establishing
* a session is interrupted. Sessions are not preemptively established in Finagle,
* rather requests are taxed with session establishment when necessary.
* For example, this exception can occur if a request is interrupted while waiting for
* an available session or if an interrupt is propagated from a Finagle server
* during session establishment.
*
* @see com.twitter.finagle.CancelledRequestException
*/
class CancelledConnectionException(cause: Throwable) extends RequestException(cause) {
def this() = this(null)
}
class ReplyCastException extends RequestException
class FailedFastException extends RequestException
class NotServableException extends RequestException
class NotShardableException extends NotServableException
class ShardNotAvailableException extends NotServableException
// Channel exceptions are failures on the channels themselves.
class ChannelException(underlying: Throwable, val remoteAddress: SocketAddress)
extends Exception(underlying) with SourcedException
{
def this(underlying: Throwable) = this(underlying, null)
def this() = this(null, null)
override def getMessage =
(underlying, remoteAddress) match {
case (_, null) => super.getMessage
case (null, _) => "ChannelException at remote address: %s".format(remoteAddress.toString)
case (_, _) => "%s at remote address: %s".format(underlying.getMessage, remoteAddress.toString)
}
}
class ConnectionFailedException(underlying: Throwable, remoteAddress: SocketAddress)
extends ChannelException(underlying, remoteAddress) with NoStacktrace {
def this() = this(null, null)
}
class ChannelClosedException(underlying: Throwable, remoteAddress: SocketAddress)
extends ChannelException(underlying, remoteAddress) with NoStacktrace {
def this(remoteAddress: SocketAddress) = this(null, remoteAddress)
def this() = this(null, null)
}
class WriteTimedOutException(remoteAddress: SocketAddress) extends ChannelException(null, remoteAddress) {
def this() = this(null)
}
class InconsistentStateException(remoteAddress: SocketAddress) extends ChannelException(null, remoteAddress) {
def this() = this(null)
}
case class UnknownChannelException(underlying: Throwable, override val remoteAddress: SocketAddress)
extends ChannelException(underlying, remoteAddress) {
def this() = this(null, null)
}
/**
* Marker trait to indicate there was an exception while writing the request.
* These exceptions should generally be retryable as the full request should
* not have reached the other end.
*/
trait WriteException extends Exception with SourcedException
/**
* Default implementation for WriteException that wraps an underlying exception.
*/
case class ChannelWriteException(underlying: Throwable)
extends ChannelException(underlying)
with WriteException
with NoStacktrace
{
override def fillInStackTrace = this
override def getStackTrace = underlying.getStackTrace
}
object WriteException {
def apply(underlying: Throwable): WriteException =
ChannelWriteException(underlying)
def unapply(t: Throwable): Option[Throwable] = t match {
case we: WriteException => Some(we.getCause)
case _ => None
}
}
case class SslHandshakeException(underlying: Throwable, override val remoteAddress: SocketAddress)
extends ChannelException(underlying, remoteAddress) {
def this() = this(null, null)
}
case class SslHostVerificationException(principal: String) extends ChannelException {
def this() = this(null)
}
case class ConnectionRefusedException(override val remoteAddress: SocketAddress)
extends ChannelException(null, remoteAddress) {
def this() = this(null)
}
case class RefusedByRateLimiter() extends ChannelException
case class FailFastException() extends ChannelException
object ChannelException {
def apply(cause: Throwable, remoteAddress: SocketAddress) = {
cause match {
case exc: ChannelException => exc
case _: java.net.ConnectException => new ConnectionFailedException(cause, remoteAddress)
case _: java.nio.channels.UnresolvedAddressException => new ConnectionFailedException(cause, remoteAddress)
case _: java.nio.channels.ClosedChannelException => new ChannelClosedException(cause, remoteAddress)
case e: java.io.IOException
if "Connection reset by peer" == e.getMessage => new ChannelClosedException(cause, remoteAddress)
case e => new UnknownChannelException(cause, remoteAddress)
}
}
}
// Transport layer errors
class TransportException extends Exception with SourcedException
class CancelledReadException extends TransportException
class CancelledWriteException extends TransportException
// Service layer errors
trait ServiceException extends Exception with SourcedException
class ServiceClosedException extends ServiceException
class ServiceNotAvailableException extends ServiceException
/**
* Indicates that the connection was not established within the timeouts.
* This type of exception should generally be safe to retry.
*/
class ServiceTimeoutException(
override protected val timeout: Duration)
extends WriteException
with ServiceException
with TimeoutException
{
override protected def explanation =
"creating a service/connection or reserving a service/connection from the service/connection pool " + serviceName
}
// Subclass this for application exceptions
class ApplicationException extends Exception
// API misuse errors.
class ApiException extends Exception
class TooManyConcurrentRequestsException extends ApiException
class InvalidPipelineException extends ApiException
class NotYetConnectedException extends ApiException
class CodecException(description: String) extends Exception(description)
// Channel buffer usage errors.
class ChannelBufferUsageException(description: String) extends Exception(description)
object BackupRequestLost extends Exception with NoStacktrace
© 2015 - 2024 Weber Informatics LLC | Privacy Policy