| Severity | Error |
| Reported by | Metalama.Framework |
| Message | An exception of type '<ExceptionType>' was thrown while <Activity>: <ExceptionMessage>. Exception details are in '<DetailsPath>'. To attach a debugger to the compiler, use the '-p:MetalamaDebugCompiler=True' command-line option. |
Cause
During compilation, Metalama executes your compile-time code: the BuildAspect and BuildEligibility methods of aspects, templates, fabrics, validators, and the constructors of these types. Metalama reports LAMA0041 when this code throws an exception that it doesn't handle.
In the message:
<Activity>describes what Metalama was executing, for instanceexecuting BuildAspect for aspect [LogAttribute] applied to 'Calculator.Add(int, int)'orexecuting the template method 'LogAttribute.OverrideMethod()';<ExceptionType>and<ExceptionMessage>are the type and the message of the exception;<DetailsPath>is the path of a text file that contains the complete exception, including its stack trace, or(none)when no file was written.
When possible, the error is reported on the target declaration of the aspect.
Some exceptions are thrown by Metalama itself, but are caused by the aspect code. For instance, Metalama throws an InvalidOperationException when an aspect adds an advice to a declaration for which this advice isn't eligible. Such exceptions are also reported as LAMA0041, and their message explains the problem.
In the following example, the Log aspect throws an exception when its Category property isn't set, and the aspect is applied without setting it.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0041.Error;
6
7public class LogAttribute : OverrideMethodAspect
8{
9 public string? Category { get; set; }
10
11 public override void BuildAspect( IAspectBuilder<IMethod> builder )
12 {
13 // The aspect throws an exception when the Category property isn't set.
14 if ( this.Category == null )
15 {
16 throw new InvalidOperationException( "The Category property of the [Log] aspect must be set." );
17 }
18
19 base.BuildAspect( builder );
20 }
21
22 public override dynamic? OverrideMethod()
23 {
24 Console.WriteLine( $"{this.Category}: executing {meta.Target.Method}." );
25
26 return meta.Proceed();
27 }
28}
29
1namespace Doc.LAMA0041.Error;
2
3internal class Calculator
4{
5 // Error: the aspect throws an exception because Category isn't set.
6 [Log]
Error LAMA0041: An exception of type 'System.InvalidOperationException' was thrown while executing BuildAspect for aspect [LogAttribute] applied to 'Calculator.Add(int, int)': The Category property of the [Log] aspect must be set. Exception details are in '(none)'. To attach a debugger to the compiler, use the '-p:MetalamaDebugCompiler=True' command-line option.
7 public int Add( int a, int b ) => a + b;
8}
9
Resolution
Read the exception message and type in the diagnostic message. If they aren't enough to find the cause, open the file given at the end of the message to see the stack trace.
Then, depending on the situation:
- If you're using the aspect, make sure that you're using it as its author intended, for instance by setting its required properties. The following example sets the
Categoryproperty. - If you're the author of the aspect, fix the bug. Instead of throwing exceptions for invalid usages, define eligibility conditions in BuildEligibility, or report an error with
builder.Diagnostics.Reportand skip the aspect with builder.SkipAspect(). Before adding an advice, check its eligibility with the IsAdviceEligible extension method of the target declaration. - To debug the compile-time code, build the project with the
-p:MetalamaDebugCompiler=Truecommand-line option, which lets you attach a debugger to the compiler.
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Code;
3using System;
4
5namespace Doc.LAMA0041.Fixed;
6
7public class LogAttribute : OverrideMethodAspect
8{
9 public string? Category { get; set; }
10
11 public override void BuildAspect( IAspectBuilder<IMethod> builder )
12 {
13 // The aspect throws an exception when the Category property isn't set.
14 if ( this.Category == null )
15 {
16 throw new InvalidOperationException( "The Category property of the [Log] aspect must be set." );
17 }
18
19 base.BuildAspect( builder );
20 }
21
22 public override dynamic? OverrideMethod()
23 {
24 Console.WriteLine( $"{this.Category}: executing {meta.Target.Method}." );
25
26 return meta.Proceed();
27 }
28}
29
1namespace Doc.LAMA0041.Fixed;
2
3internal class Calculator
4{
5 // Fixed: Category is set, so the aspect doesn't throw.
6 [Log( Category = "Math" )]
7 public int Add( int a, int b ) => a + b;
8}
9
1using System;
2
3namespace Doc.LAMA0041.Fixed;
4
5internal class Calculator
6{
7 // Fixed: Category is set, so the aspect doesn't throw.
8 [Log(Category = "Math")]
9 public int Add(int a, int b)
10 {
11 Console.WriteLine("Math: executing Calculator.Add(int, int).");
12 return a + b;
13 }
14}
15