Open sandboxFocusImprove this doc

LA0014: Aspect Constructor or Property Setter Threw an Exception

Severity Error
Reported by PostSharp
Message <ExceptionMessage>

Cause

PostSharp creates the aspect instances at build time: for each custom attribute that is an aspect, it calls the constructor of the aspect class with the arguments of the attribute, then the setters of the properties that the attribute names. When the constructor or a setter throws an exception, PostSharp cannot create the aspect and reports LA0014.

<ExceptionMessage> names the aspect class, the constructor or the property setter that failed, and the exception with its message. When the constructor failed because an assembly could not be loaded, the message also describes the failed binding.

PostSharp reports the message on the aspect class, not on the declaration to which the aspect is applied. When the aspect is applied in several places, look for the usages that pass the value that the exception message rejects.

In the following example, the setter of the Category property rejects an empty string, and PlaceOrder sets it to one.

using System;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.LA0014_Error;

[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
    private string category = "General";

    public string Category
    {
        get => this.category;
        set
        {
            if ( string.IsNullOrEmpty( value ) )
            {
                throw new ArgumentException( "The category cannot be empty." );
            }

            this.category = value;
        }
    }

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"[{this.Category}] Entering {args.Method.Name}." );
    }
}

public class OrderService
{
    // PostSharp runs the property setter at build time, and the setter throws.
    [Log( Category = "" )]
    public void PlaceOrder( string product )
    {
        Console.WriteLine( $"Order placed for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Coffee" );
    }
}
error LA0014: LA0014_Error.cs(8,14): The custom attribute 'Errors.LA0014_Error.LogAttribute' property setter 'Category' threw the exception ArgumentException: The category cannot be empty.

Resolution

  • Pass arguments that the constructor and the setters of the aspect accept.
  • When the check of the aspect is meant to report a usage error, move it from the constructor or the setter to CompileTimeValidate, and report a message with Write: the message then has the location of the declaration to which the aspect is applied.

In the following example, PlaceOrder gives a valid category.

using System;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.LA0014_Fixed;

[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
    private string category = "General";

    public string Category
    {
        get => this.category;
        set
        {
            if ( string.IsNullOrEmpty( value ) )
            {
                throw new ArgumentException( "The category cannot be empty." );
            }

            this.category = value;
        }
    }

    public override void OnEntry( MethodExecutionArgs args )
    {
        Console.WriteLine( $"[{this.Category}] Entering {args.Method.Name}." );
    }
}

public class OrderService
{
    // The category is valid, so the property setter accepts it.
    [Log( Category = "Orders" )]
    public void PlaceOrder( string product )
    {
        Console.WriteLine( $"Order placed for {product}." );
    }
}

public static class Program
{
    public static void Main()
    {
        new OrderService().PlaceOrder( "Coffee" );
    }
}
[Orders] Entering PlaceOrder.
Order placed for Coffee.

See Also

Reference

CompileTimeValidate

Other Resources

Validating Aspect Usage
Understanding Aspect Lifetime and Scope