MatchException#

The exception thrown by SkillLayer.slots and SkillLayer.validatePool. It reports an invalid item in the pool or the requirements, or a project state that doesn't allow building slots. It's an unchecked RuntimeException but not a PlenException, so catch (PlenException e) doesn't catch it. toPlenException() converts it to one.

Declaration#

package org.dhtmlx.plen;

public abstract class MatchException extends RuntimeException {
  public MatchException(String message, RuntimeException inner)
  public MatchException(String message)

  public abstract PlenException toPlenException()

  public static class Invalid extends MatchException { ... }
  public static class Project extends MatchException { ... }
}

The class is abstract. Every thrown value is one of the two nested subclasses. Catch them separately, or catch MatchException and test with instanceof.

Java 21 also defines java.lang.MatchException. With only import org.dhtmlx.plen.*;, the simple name MatchException is ambiguous and doesn't compile. Import the class by name:

import org.dhtmlx.plen.*;
import org.dhtmlx.plen.MatchException;

Methods#

toPlenException#

public abstract PlenException toPlenException()

Returns the equivalent engine exception, so a method that calls both slots and Project#suggestAssignments can rethrow it and handle one exception type.

Subclass Returns
Invalid A new InputException of kind VALIDATION, with the same path and detail as its message
Project The wrapped ProjectException (error), not a copy

Variants#

Variant When it occurs
Invalid An item of the pool or a requirement is invalid. path names the item, detail says what's wrong
Project The project has no accepted baseline: it's unsolved, or it has unsolved edits after apply. code() returns ProjectError.NO_BASELINE

Invalid#

An invalid pool or requirement. Thrown by slots and validatePool; validatePool throws it only for pool.workers[...] paths.

public static class Invalid extends MatchException {
  public String path;
  public String detail;

  public Invalid(String path, String message)

  public MatchException.Invalid withPath(String value)
  public MatchException.Invalid withDetail(String value)
  public PlenException toPlenException()
}
Member Type Description
path String The invalid item, for example requirements[2].assignments[0]
detail String What's wrong with the item
getMessage() String "<path>: <detail>", built by the constructor. Not updated by withPath / withDetail
getCause() Throwable null

path values:

Path When it occurs
pool.workers[i].resource Unknown resource, or the same resource listed as two workers
pool.workers[i].skills[j].id The same skill listed twice on one worker
pool.workers[i].skills[j].value Not finite
requirements[i].id Duplicate requirement id, or one of its slot ids is an active assignment on another task
requirements[i].task Unknown or unscheduled task
requirements[i].count 0
requirements[i].units Not finite, or <= 0
requirements[i].matches[j].value Not finite
requirements[i].assignments More entries than count, or an assignment with one of this requirement's slot ids is left out of the list
requirements[i].assignments[k] Unknown or inactive assignment, an assignment on another task, or an assignment bound twice

Project#

The project state doesn't allow building slots. slots throws it with a ProjectException of code NO_BASELINE.

public static class Project extends MatchException {
  public ProjectException error;

  public Project(ProjectException error)

  public MatchException.Project withError(ProjectException value)
  public ProjectError code()
  public PlenException toPlenException()
}
Member Type Description
error ProjectException The wrapped project-state exception
code() ProjectError error.code
getMessage() String The message of error, the kebab-case code, for example no-baseline
getCause() Throwable error

The constructor throws NullPointerException when error is null.

Example#

import java.util.List;
import org.dhtmlx.plen.*;
import org.dhtmlx.plen.MatchException;

public class MatchExceptionExample {
  public static void main(String[] args) throws Exception {
    Project project = new Project(); // never solved

    try {
      SkillLayer.slots(project, new Pool(), List.of());
    } catch (MatchException.Project e) {
      System.out.println("project state: " + e.code()); // NO_BASELINE
    } catch (MatchException.Invalid e) {
      System.out.println(e.path + ": " + e.detail);
    }
  }
}