@@ -0,0 +1,2396 @@
+// Copyright (C) 2021 The Android Open Source Project%0A//%0A// Licensed under the Apache License, Version 2.0 (the %22License%22);%0A// you may not use this file except in compliance with the License.%0A// You may obtain a copy of the License at%0A//%0A// http://www.apache.org/licenses/LICENSE-2.0%0A//%0A// Unless required by applicable law or agreed to in writing, software%0A// distributed under the License is distributed on an %22AS IS%22 BASIS,%0A// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A// See the License for the specific language governing permissions and%0A// limitations under the License.%0A%0Apackage com.google.gerrit.server.cancellation;%0A%0Aimport com.google.gerrit.common.Nullable;%0Aimport java.util.Optional;%0A%0A/** Exception to signal that the current request is cancelled and should be aborted. */%0Apublic class RequestCancelledException extends RuntimeException %7B%0A  private static final long serialVersionUID = 1L;%0A%0A  private final RequestStateProvider.Reason cancellationReason;%0A  private final Optional%3CString%3E cancellationMessage;%0A%0A  /**%0A   * Create a %7B@code RequestCancelledException%7D.%0A   *%0A   * @param cancellationReason the reason why the request is cancelled%0A   * @param cancellationMessage an optional message providing details about the cancellation%0A   */%0A  public RequestCancelledException(%0A      RequestStateProvider.Reason cancellationReason, @Nullable String cancellationMessage) %7B%0A    super(createMessage(cancellationReason, cancellationMessage));%0A    this.cancellationReason = cancellationReason;%0A    this.cancellationMessage = Optional.ofNullable(cancellationMessage);%0A  %7D%0A%0A  private static String createMessage(%0A      RequestStateProvider.Reason cancellationReason, @Nullable String message) %7B%0A    StringBuilder messageBuilder = new StringBuilder();%0A    messageBuilder.append(String.format(%22Request cancelled: %25s%22, cancellationReason.name()));%0A    if (message != null) %7B%0A      messageBuilder.append(String.format(%22 (%25s)%22, message));%0A    %7D%0A    return messageBuilder.toString();%0A  %7D%0A%0A  /** Returns the reason why the request is cancelled. */%0A  public RequestStateProvider.Reason getCancellationReason() %7B%0A    return cancellationReason;%0A  %7D%0A%0A  /**%0A   * Returns a message providing details about the cancellation, or %7B@link Optional#empty()%7D if none%0A   * is available.%0A   */%0A  public Optional%3CString%3E getCancellationMessage() %7B%0A    return cancellationMessage;%0A  %7D%0A%7D%0A

Define an exception that is thrown if a request is cancelled