001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.cli.processor.command;
007
008import dev.metaschema.cli.processor.ExitCode;
009import dev.metaschema.cli.processor.ExitStatus;
010import edu.umd.cs.findbugs.annotations.NonNull;
011
012/**
013 * For use in commands to short-circut command execution.
014 */
015public class CommandExecutionException
016    extends Exception {
017  /**
018   * The exit code indicating the type of error that occurred.
019   */
020  private final ExitCode exitCode;
021
022  /**
023   * the serial version UID.
024   */
025  private static final long serialVersionUID = 1L;
026
027  /**
028   * Constructs a new exception with the provided {@code code}, and no message or
029   * cause.
030   *
031   * @param code
032   *          the exit code associated with this error
033   */
034  public CommandExecutionException(@NonNull ExitCode code) {
035    this.exitCode = code;
036  }
037
038  /**
039   * Constructs a new exception with the provided {@code code}, {@code message},
040   * and no cause.
041   *
042   * @param code
043   *          the exit code associated with this error
044   * @param message
045   *          the exception message
046   */
047  public CommandExecutionException(@NonNull ExitCode code, String message) {
048    super(message);
049    this.exitCode = code;
050  }
051
052  /**
053   * Constructs a new exception with no message and the provided {@code code} and
054   * {@code cause}.
055   *
056   * @param code
057   *          the exit code associated with this error
058   * @param cause
059   *          the original exception cause
060   */
061  public CommandExecutionException(@NonNull ExitCode code, Throwable cause) {
062    super(cause);
063    this.exitCode = code;
064  }
065
066  /**
067   * Constructs a new exception with the provided {@code code}, {@code message},
068   * and {@code cause}.
069   *
070   * @param code
071   *          the exit code associated with this error
072   * @param message
073   *          the exception message
074   * @param cause
075   *          the original exception cause
076   */
077  public CommandExecutionException(@NonNull ExitCode code, String message, Throwable cause) {
078    super(message, cause);
079    this.exitCode = code;
080  }
081
082  /**
083   * Generate an {@link ExitStatus} based on this exception.
084   *
085   * @return the exit status
086   */
087  @NonNull
088  public ExitStatus toExitStatus() {
089    String message = getLocalizedMessage();
090
091    ExitStatus retval = message == null
092        ? exitCode.exit()
093        : exitCode.exitMessage(message);
094
095    Throwable cause = getCause();
096    if (cause != null) {
097      retval.withThrowable(cause);
098    }
099    return retval;
100  }
101}