# LS1005: Domain Throws a Non-Domain Exception

## Intent

LS1005 is a compiler check that reports a throw in Domain, the project that holds business rules, of an exception that is not a DomainException subclass, which would reach the caller with no stable failure code and no business meaning. This page states what the rule reports, where the warning sits, and how to throw a DomainException subclass instead.

## Reference

### What the rule enforces

LS1005 enforces [Reject business violations with Domain exceptions](https://litespec.dev/2.0.0/backend/dotnet/domain.md#reject-business-violations-with-domain-exceptions) (`litespec/backend/dotnet/domain#reject-business-violations-with-domain-exceptions`). It runs in Domain only. Its category is `LiteSpec.Domain`. It reports a warning and is enabled by default, as the [Analyzers overview](https://litespec.dev/2.0.0/analyzers/README.md) describes.

### What the rule reports

The rule reports a `throw` of any exception that is not a `DomainException` subclass. The diagnostic sits on the thrown expression, for example on `new InvalidOperationException()`, and its message names the thrown type.

### Failing example

```csharp
public void Place()
{
    throw new InvalidOperationException();
}
```

### Passing example

```csharp
public void Place(bool placed)
{
    if (placed)
    {
        throw new OrderAlreadyPlacedException();
    }
}
```

### How to fix

Throw a `DomainException` subclass named `{DomainType}{Reason}Exception` for the rejected business rule, and keep `ArgumentException` for argument guards.

## Notes

### What the rule ignores

The rule does not report a throw of a `DomainException` subclass, an argument guard that throws `ArgumentException` or one of its subclasses, a throw of `UnreachableException`, a bare `throw;`, or a throw of a caught variable. It does not run outside Domain.
