New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StackTrace when catch the exception #1201
Comments
The method call to Now let's assume that you just accidentally reduced your example too much. using static LanguageExt.Prelude;
using LanguageExt;
using LanguageExt.Sys.Live;
static Aff<Runtime, int> F1() => unitAff.Bind(_ => F2());
static Aff<Runtime, int> F2() => unitAff.Bind(_ => F3());
static Aff<Runtime, int> F3() => unitAff.Bind(_ => F4());
static Aff<Runtime, int> F4() =>
from r in SuccessAff(1)
from r2 in guard(false, () => throw new Exception())
select r;
try
{
F1().Run(Runtime.New()).Result.ThrowIfFail();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
} I am afraid this example won't show a better stack trace. I am not aware of a general way to get more details where the failed effect came from. |
Well, this is the actual callstack, therefor there's no way to achieve a better one using monads. However, error handling with monads works differently. For example, instead of just throwing a random exception in your guard, try to create a meaningful error which tells you what was wrong, or if you can't, where it went wrong |
Collecting information (sort of analogous to unwinding the stack) as the Error moves through the bind chains is not impossible, just not necessarily going to provide useful information. Using compiler attributes you can get the line number and source file of the invokation point of the Error, it might be a starting point for something better. I know that ZIO has built in support for tracing errors produced under concurrent loads. Would have to investigate how that works and if can be replicated. |
Here is an approach, which I don't recommend: using static LanguageExt.Prelude;
using LanguageExt;
using LanguageExt.Sys.Live;
using System.Runtime.CompilerServices;
using LanguageExt.Common;
static Aff<Runtime, int> F1() => unitAff.Bind(_ => F2()).MapFail(e => AddTraceInfo(e));
static Aff<Runtime, int> F2() => unitAff.Bind(_ => F3()).MapFail(e => AddTraceInfo(e));
static Aff<Runtime, int> F3() => unitAff.Bind(_ => F4()).MapFail(e => AddTraceInfo(e));
static Aff<Runtime, int> F4()
=> (from r in SuccessAff(1)
from r2 in guard(false, () => throw new Exception())
select r).MapFail(e => AddTraceInfo(e));
static Error AddTraceInfo(
Error error,
[CallerLineNumber] int lineNumber = 0,
[CallerMemberName] string? caller = null)
=> error.Append($"Failed in {caller} line {lineNumber}.");
try
{
F1().Run(Runtime.New()).Result.ThrowIfFail();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
} Output:
|
What would be the best outcome for the developer debugging the code? Some things that I would want,
All three can be accomplished with no fundamental library changes,
I don't think I would miss stack traces if I had access to all that. The issue might still be that the developer who has no understanding of effects, would still be thrown by the stack trace, end up on the wrong line and waste time. Not sure I have the solution to that, but might be another area to explore. |
But isn't the problem, that there is not enough contextual information without a stack trace replacement? I'd imagine having a |
We are using this library for over four years, and we love it. We almost use language.ext around 99% in our coding.
And now we are facing the issue that hard to tracing the code calling stack when there is exception throw.
For example in following code
And here is the exception's stackTrace.
When we get the exception in our system log, we can only know It is throw in the line 14 (F4()), and the entry location is from line 18,
But we cannot getting the function calling stack for it actually calling the path F1 => F2 => F3 => F4.
Is there any suggestion on how to improve the code so that we can get the actual function calling stack when we got the exception
The text was updated successfully, but these errors were encountered: