[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [8ab18d3](https://github.com/UnigramDev/Unigram/commit/8ab18d3bbfbe95348c94d1f62e0e973ba7927fc6) • _2 files, +90/-30_
Keep the originating description when an unhandled error is a bare E_FAIL (#3340)

* Keep the originating description when an unhandled error is a bare E_FAIL

A large share of unhandled errors reach OnUnhandledExceptionDetected as an
E_FAIL with no message and a stack that only shows Propagate() rethrowing it.
GetStowedException already tries to recover the real context, but it returns
null unless every step succeeds, so those reports carry nothing.

Read the description out of IRestrictedErrorInfo before giving up, and return
what was recovered even when the stowed frames are unavailable. The call was
already written out in a comment and left unused on the assumption that the
propagated managed exception would carry the details - which is exactly what
fails here.

WatchDog no longer overwrites the recovered string with the empty one from the
propagated exception.

* Read the rest of the stowed exception record

GetStowedException2 required ExceptionForm 1 and returned null otherwise, so
three fields the record always carries went unused:

- ResultCode, the HRESULT the error was stowed with, before propagation
  flattened it to E_FAIL. This is the field that actually distinguishes one
  failure from another.
- ThreadId, the thread it originated on, which is not necessarily the one whose
  stack ends up in the report.
- ErrorText, which form 2 carries instead of a stack, and which was discarded
  along with the whole record.

It also returned null when no frame resolved a module base, dropping the above
and the nested record with them. Now a FatalError is returned either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

[#unigram](?q=%23unigram)