WorkflowSessionException.java
package org.hammer.audio.workflow.collaboration;
import java.io.Serial;
import java.util.Objects;
/** Typed application error for workflow-session lifecycle and command failures. */
public class WorkflowSessionException extends RuntimeException {
@Serial private static final long serialVersionUID = 1L;
/** Stable error codes independent of HTTP or any other transport. */
public enum Code {
SESSION_ALREADY_EXISTS,
SESSION_NOT_FOUND,
PRIVATE_WORKSPACE_ACCESS_DENIED,
ACTOR_METADATA_MISMATCH,
ACTOR_NOT_JOINED,
SESSION_MODE_MISMATCH,
SESSION_CLOSE_FORBIDDEN,
DUPLICATE_OPERATION_ID,
INVALID_OPERATION_AUTHOR,
UNDO_TARGET_REQUIRED,
UNDO_TARGET_NOT_FOUND,
OPERATION_NOT_UNDOABLE,
UNDO_PREVIEW_REQUIRED,
UNDO_PREVIEW_STALE,
UNDO_CONFLICT,
REDO_TARGET_NOT_FOUND,
REDO_TARGET_INVALID,
REDO_ALREADY_APPLIED
}
private final Code errorCode;
private final String relatedSessionId;
/** Creates a typed session exception. */
public WorkflowSessionException(Code code, String sessionId, String message) {
super(validateBeforeConstruction(code, message));
this.errorCode = code;
this.relatedSessionId = sessionId;
}
/** Returns the stable transport-independent error code. */
public Code code() {
return errorCode;
}
/** Returns the related session id, or {@code null} when none is available. */
public String sessionId() {
return relatedSessionId;
}
private static String validateBeforeConstruction(Code code, String message) {
Objects.requireNonNull(code, "code");
return Objects.requireNonNull(message, "message");
}
}