Commit b43e72a
committed
fix(core): AggregateException composes its message unconditionally (#2309)
SR-AUD-098 clauses C2/C3/C4. AggregateException("outer", {a, b}) reported "outer"
and DISCARDED the contained diagnostics; .NET composes unconditionally whenever
there are inner exceptions.
THE TICKET'S TWO BLOCKING GROUNDS ANSWER EACH OTHER.
Ground 1 was representation: composition (C2) and preservation (C3/C4) cannot both
hold under ONE stored string. The ticket measured all five candidate models --
closing C2 alone works, closing C3/C4 alone works, and closing BOTH yields
"custom outer (a) (b) (a) (b)" and GROWS WITHOUT BOUND under repeated Flatten().
The only escape is a second std::string, which is exactly SA-3's case: a private
data member on a public type with no vtable, mangled-symbol, signature or noexcept
change. Taken. sizeof(AggregateException) 192 -> 224 and
sizeof(UnobservedTaskExceptionEventArgs) -- a public header holding one by value --
208 -> 240, both pinned by a layout test. Consumers must rebuild; no source change.
Ground 2 was the reference text, and /rv settles it:
if (_innerExceptions.Length == 0) return base.Message;
sb.Append(base.Message); sb.Append(' ');
for (...) { sb.Append('('); sb.Append(_innerExceptions[i].Message); sb.Append(") "); }
sb.Length--; -- AggregateException.cs:339-360
Two details are transcribed rather than reconstructed. The composition is
UNCONDITIONAL when there are leaves -- this port composed only for the DEFAULT
message, which is the C2 defect and an inconsistency with itself. And the trailing
`sb.Length--` means the string ends at ")" with no trailing space; that is
reproduced by appending ") " and dropping the last character rather than by
special-casing the final element, so the two spellings cannot drift apart.
FLATTEN AND HANDLE DIFFER, AND THAT IS .NET'S DOING.
Flatten: new AggregateException(GetType() == typeof(AggregateException)
? base.Message : Message, ...) :335
Handle: throw new AggregateException(Message, unhandled.ToArray(), ...) :281
Flatten passes the RAW message for a plain AggregateException and the COMPOSED one
for a derived type -- and that discrimination is precisely what stops repeated
flattening from accreting leaf text, which is the pathology the ticket measured.
Handle passes the COMPOSED one, so a rethrown aggregate legitimately lists its
leaves twice. The two are transcribed separately rather than sharing a helper that
would hide the difference. typeid is the C++ counterpart of GetType(), and this
class is polymorphic, so it reads the dynamic type as .NET's does.
The composition runs in the CONSTRUCTOR rather than the getter. That is
observationally identical rather than a shortcut: innerExceptions_ is fixed at
construction and never mutated, here and in .NET, where _innerExceptions is a
ReadOnlyCollection assigned once. Composing on access would additionally force
getMessageProperty() to stop returning const std::string&, which is a public
signature change this needs no part of.
Three pins inverted, four cases added. Five mutations, all caught.
ALSO REPAIRED: a pre-existing flake this ticket's gate run caught.
StopwatchDefinedArithmeticTests.Fix2326_TheResolutionThatWasLost took 200 pairs of
back-to-back timestamps and required the smallest positive delta to be under 100
units -- which measures the MACHINE, not the code. It passed eight times out of
eight in isolation and failed once inside a full gate, where any of the 200 pairs
can be preempted. The property is a UNIT, so it is now asserted against a unit:
GetTimestamp() samples steady_clock's own epoch, so a division by 100 would put its
value two orders of magnitude below the same clock read directly. A comparison of
values, immune to scheduling -- and it still catches the mutation that restores the
division. A test that is intermittently green is not evidence (#2352).
Downstream: neither cna nor mobile-eggbert references AggregateException -- zero
sites in both. The rebuild requirement is recorded for any future consumer.
Gate: 17,333 run, 17,333 passed, 0 failed, 0 skipped across 38 executables, GREEN,
confirmed by two consecutive full runs.
docs/Migration-AggregateExceptionRawMessage.md1 parent 839c101 commit b43e72a
6 files changed
Lines changed: 341 additions & 39 deletions
File tree
- docs
- modules/core
- include/System
- tests/System
- Diagnostics
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
26 | 52 | | |
27 | 53 | | |
28 | 54 | | |
| |||
98 | 124 | | |
99 | 125 | | |
100 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
101 | 155 | | |
102 | | - | |
103 | | - | |
104 | | - | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
105 | 159 | | |
| 160 | + | |
106 | 161 | | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
116 | 165 | | |
117 | | - | |
| 166 | + | |
118 | 167 | | |
119 | 168 | | |
120 | 169 | | |
121 | 170 | | |
122 | 171 | | |
123 | | - | |
| 172 | + | |
| 173 | + | |
124 | 174 | | |
125 | 175 | | |
126 | | - | |
| 176 | + | |
| 177 | + | |
127 | 178 | | |
128 | 179 | | |
129 | 180 | | |
130 | 181 | | |
131 | 182 | | |
132 | 183 | | |
133 | 184 | | |
134 | | - | |
| 185 | + | |
| 186 | + | |
135 | 187 | | |
136 | 188 | | |
137 | 189 | | |
| |||
145 | 197 | | |
146 | 198 | | |
147 | 199 | | |
148 | | - | |
149 | | - | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
150 | 204 | | |
151 | 205 | | |
152 | 206 | | |
| |||
159 | 213 | | |
160 | 214 | | |
161 | 215 | | |
162 | | - | |
163 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
164 | 219 | | |
165 | 220 | | |
166 | 221 | | |
| |||
263 | 318 | | |
264 | 319 | | |
265 | 320 | | |
266 | | - | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
267 | 335 | | |
268 | 336 | | |
269 | 337 | | |
| |||
289 | 357 | | |
290 | 358 | | |
291 | 359 | | |
292 | | - | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
293 | 366 | | |
294 | 367 | | |
295 | 368 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
241 | 241 | | |
242 | 242 | | |
243 | 243 | | |
244 | | - | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
252 | 261 | | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
253 | 267 | | |
254 | 268 | | |
255 | 269 | | |
| |||
0 commit comments