InputException#

Thrown when the data or options passed to a call are invalid. It derives from PlenException, so catch (PlenException) also catches it. The engine creates it. You rarely construct one yourself.

Declaration#

namespace Plen;

public sealed class InputException : PlenException
{
    public InputException(InputErrorKind kind, string message, string? path = null);
    public static InputException Validation(string path, string message);
    public InputErrorKind Kind { get; }
    public string? Path { get; }
}

Constructors#

InputException#

public InputException(InputErrorKind kind, string message, string? path = null)

Creates an input error.

Name Type Description
kind InputErrorKind Parse or Validation.
message string The error description, stored in Message.
path string? The input field the error refers to, such as tasks[2].duration. Optional; default null.

Properties#

Kind#

public InputErrorKind Kind { get; }

Whether the input couldn't be decoded (Parse) or decoded but is invalid (Validation). Calls in the Plen.Core and Plen.Assign packages throw only Validation.

Path#

public string? Path { get; }

The field the error refers to, in its JSON (wire) spelling with snake_case names and zero-based indexes: tasks[0].constraint_date, calendars[1].worktime.days, slots[2].value. It's null when the error concerns the whole input or state rather than one field, such as SuggestAssignments on a cyclic project.

Message#

public virtual string Message { get; }

Inherited from Exception. The description only, such as invalid duration or duplicate task id, without the path or kind. Read Path as well when you show the error to a user.

Static methods#

Validation#

public static InputException Validation(string path, string message)

Creates an error with Kind set to Validation.

Name Type Description
path string The field the error refers to.
message string The error description.

Returns the new InputException.

Thrown by#

Call When
Project.Solve The replacement data is invalid. The previous state and its cached result are kept.
Project.Preview An operation in the changes is rejected, or the Profile query is invalid.
Project.Analyze The supplied data is invalid.
Project.Level The scope names an unknown resource or task, or the config schedules from the end.
Project.LoadProfile The range is empty or has too many buckets, or a resource is unknown.
Project.Evaluate, EvaluateWith A focus id is unknown, or the Level options are invalid for the baseline.
Project.SuggestAssignments An option or slot is invalid, or the accepted state has a cycle.
Engine.Schedule The data is invalid.
SkillLayer.Slots The resource pool or a requirement is invalid.

Project.Apply doesn't throw it: rejected operations come back in ApplyReport.Rejected. The validation rules for project data are on ProjectData. The Validation mode decides whether fixable input is rejected or repaired.

InputErrorKind#

The kind of an InputException.

namespace Plen;

public enum InputErrorKind
{
    Parse,
    Validation,
}
Value Description
Parse The input couldn't be decoded. Only the JSON decoders of the separate Plen.Wire package produce it.
Validation The input decoded but is invalid. Every call in this package produces this kind.

Example#

using Plen;

var monday = Moment.FromYmdHm(2026, 3, 2, 8, 0) ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks =
    [
        new TaskData("ok") { StartDate = monday, Duration = 1 },
        new TaskData("broken") { Duration = 2 }, // only one of start, end and duration
    ],
};

try
{
    Engine.Schedule(data, new SolveOptions());
}
catch (InputException e) when (e.Kind == InputErrorKind.Validation)
{
    Console.WriteLine($"{e.Path ?? "(input)"}: {e.Message}");
}