Skip to content

Commit 27082d0

Browse files
authored
feat(Unity): Troubleshooting explainer for <>n__0 (#15196)
1 parent 6d53857 commit 27082d0

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

docs/platforms/unity/troubleshooting/known-limitations.mdx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,58 @@ Your stack traces might contain C++ frames. This might be because:
4545

4646
This is also why you might end up with very high line numbers (in the several thousands) even though your C# script is very small; the line numbers relate to the generated C++ code.
4747

48+
### Stack traces contain frames with `<>n__0`, `<>c`, or `<>c__DisplayClass`
49+
50+
When viewing stack traces in Sentry, you may encounter compiler-generated class and method names with patterns like `<>c`, `<>c__DisplayClass#_#`, `<>n__0`, or `{ <lambda> }`. These are created by the C# compiler when you use:
51+
52+
- **Lambda expressions**: Anonymous functions like `items.Where(x => x.IsActive)`
53+
- **Delegates**: Inline delegate definitions such as `Action`, `Func`
54+
- **LINQ expressions**: Query syntax and method chains
55+
- **Async/await**: State machine methods for asynchronous operations (may show `MoveNext`)
56+
- **Iterator methods**: Coroutines and methods using `yield return` (may show `MoveNext`)
57+
- **Event handlers**: Lambda expressions in event subscriptions
58+
- **UI callbacks**: Unity button click handlers like `button.onClick.AddListener(() => {...})`
59+
60+
**Common patterns you'll see:**
61+
62+
| Pattern | What it means | Example |
63+
|---------|---------------|---------|
64+
| `YourClass+<>c` | Cached delegate class for simple lambdas | `YourClass+<>c in ThrowExceptionInLinq { <lambda> }` |
65+
| `YourClass+<>c__DisplayClass#_#` | Display class for closures that capture local variables | `YourClass+<>c__DisplayClass12_0 in ThrowExceptionInClosure { <lambda> }` |
66+
| `<>n__0`, `<>n__1` | Compiler-generated method names (may appear in detailed stack traces) | Method name suffix distinguishing multiple lambdas |
67+
| `{ <lambda> }` | Indicates the frame is from a lambda expression | Shown in Sentry issue titles |
68+
| `MoveNext` | State machine method for async/await or iterator methods | Common in async methods and Unity coroutines |
69+
70+
**Example:**
71+
72+
If your code contains:
73+
```csharp
74+
public void ThrowExceptionInLinq()
75+
{
76+
var numbers = new List<int> { 1, 2, 3, 4, 5 };
77+
var result = numbers.Where(n =>
78+
{
79+
if (n == 3) throw new InvalidOperationException("Error!");
80+
return n > 2;
81+
}).ToList();
82+
}
83+
```
84+
85+
The Sentry issue will show something like:
86+
```
87+
YourClass+<>c in ThrowExceptionInLinq { <lambda> }
88+
```
89+
90+
**How to interpret these frames:**
91+
92+
1. **`+<>c`**: The `+` indicates a nested class. `<>c` is a cached delegate class that holds the lambda's compiled code
93+
2. **`+<>c__DisplayClass#_#`**: Similar to `<>c`, but used when the lambda captures local variables (creates a "closure")
94+
3. **Method name shown**: Look at the parent method name (after "in") to identify where in your code the lambda was defined
95+
4. **`{ <lambda> }`**: Confirms the exception occurred inside the lambda expression itself
96+
5. **`MoveNext`**: For async methods and coroutines, this is the state machine method that executes your code
97+
98+
These frames are normal and expected in C# applications. They provide precise information about where an exception occurred within lambda expressions and compiler-generated code.
99+
48100
## Cysharp
49101

50102
**Note: This issue is obsolete and resolved for Unity 2021+ with UniTask 2.5.10+**

0 commit comments

Comments
 (0)