All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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()
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy