[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/plen-exception/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# PlenException

Abstract base of every exception the engine throws: [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) for invalid input, and [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>) for a call that doesn't fit the project's state. You never create one directly. Catch it to handle any engine failure in one place.

## Declaration

```csharp
namespace Plen;

public abstract class PlenException : Exception
```

The constructor is `private protected`, so [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) and [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>) are the only subclasses. Both are `sealed`.

## Properties

### Message

```csharp
public override string Message { get; }
```

Inherited from `Exception`. The text depends on the subclass: the validation message for [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>), the kebab-case error code for [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>).

## Subclasses

| Subclass | When it occurs |
|---|---|
| [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) | The input is invalid. `Kind` and `Path` say what failed and where. |
| [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>) | The call doesn't fit the project's state. `Code` names the state. |

Each operation page lists which of the two it throws. Framework exceptions (`ArgumentNullException` for a `null` argument, and others) don't derive from `PlenException`. Conflicts, cycles, failure to converge and rejected `Apply` operations are reported in results, not thrown. See [Error handling](<https://docs.dhtmlx.com/planning-engine/net/error-handling.md>).

## Example

```csharp
using Plen;

var data = new ProjectData
{
    // A task needs at least two of StartDate, EndDate and Duration.
    Tasks = [new TaskData("design") { Duration = 2.0 }],
};

var project = new Project();

try
{
    project.Solve(data, new SolveOptions());
}
catch (PlenException ex)
{
    switch (ex)
    {
        case InputException input:
            Console.WriteLine($"Invalid input at {input.Path}: {input.Message}");
            break;
        case ProjectException state:
            Console.WriteLine($"Project state: {state.Code}");
            break;
    }
}
```

## Related

- [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) - thrown for invalid input
- [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>) - thrown when a call doesn't fit the project's state
- [Error handling](<https://docs.dhtmlx.com/planning-engine/net/error-handling.md>) - how failures surface and how to recover
