com.seeq.utilities.exception.OperationCanceledException.kt Maven / Gradle / Ivy
The newest version!
package com.seeq.utilities.exception
fun Exception.rethrowIfCancellation() = (this as? OperationCanceledException)?.let { throw this }
/**
* Indicates that an operation was intentionally aborted. Every method in this system may throw this exception. This
* exception can only be consumed by the originator of the operation (e.g REST interface). Other methods may catch this
* exception, but this exception must be re-thrown.
*
* **NOTE(spencer):** as of CRAB-17847, `com.seeq.appserver.monitoring.Timer` refers to this class using a
* hard-coded string constant as a way to implement `instanceof`. That means any descendants of this class
* won't be detected by that check, so I've marked this class `final` to avoid errors. If you extend this
* class, you'll need to update the logic in Timer.
*/
class OperationCanceledException : RuntimeException {
val isRestartRequested: Boolean
/** The operation was canceled. */
constructor() : super() {
isRestartRequested = false
}
/**
* The operation was canceled and additional information is available.
*
* @param message
* Additional information about the cancellation.
*/
constructor(message: String) : super(message) {
isRestartRequested = false
}
/**
* The operation was canceled and additional information is available.
*
* @param cause
* The cause of the cancellation (e.g. an InterruptedException).
*/
constructor(cause: Throwable) : super(cause) {
isRestartRequested = false
}
/**
* The operation was canceled and additional information is available.
*
* @param message
* Additional information about the cancellation.
* @param cause
* The cause of the cancellation (e.g. an InterruptedException).
*/
constructor(message: String, cause: Throwable?) : super(message, cause) {
isRestartRequested = false
}
/**
* The operation was canceled but should be restarted or retried if so specified.
*
* @param restartRequested
* True if the request should be restarted or retried after cancellation.
*/
constructor(restartRequested: Boolean) : super() {
isRestartRequested = restartRequested
}
companion object {
private const val serialVersionUID = 351898195383339572L
/**
* Checks if this thread has been interrupted, and throws an [OperationCanceledException] if so.
*
* This is necessary anywhere we want to check for cancellation where no blocking methods are called. Methods such
* as Thread.sleep or Future.get that throw an InterruptedException will check, but in situations where Futures are
* merely being issued (but not retrieved) or in tight computation loops, explicitly checking is necessary.
*/
@JvmStatic
fun checkForCancellation() {
// This check clears the interrupted status of the thread, which is what we want. Once we've generated an
// exception based on the interrupted status we don't want the thread to be forever tainted by once having
// been interrupted.
if (Thread.interrupted()) {
throw OperationCanceledException()
}
}
}
}