.Net: [Error handling] [Part7] Removing IsCriticalException extension method - #2516
.Net: [Error handling] [Part7] Removing IsCriticalException extension method#2516SergeyMenshykh wants to merge 2 commits into
Conversation
lemillermicrosoft
left a comment
There was a problem hiding this comment.
Why are we removing IsCriticalException? The ADR only mentions it in that it will be updated to include StackOverflowException and OutOfMemoryException.
dmytrostruk
left a comment
There was a problem hiding this comment.
As mentioned by @lemillermicrosoft , would be nice to see updates in ADR with details why IsCriticalException is removed/replaced.
Yes, right, it's not part of ADR. It popped up later as a comment in one of the 'Erro handling' PRs where we (@rogerbarreto , @stephentoub and me) agreed that there's no value in having it. Let's discuss this on parking lot. CC: @shawncal |
rogerbarreto
left a comment
There was a problem hiding this comment.
By removing the function IsCriticalException we are pratically considering any exceptions to be "critical" (should throw), I would expect the change to be either:
- Remove all the catch block
- Keep the catch just to log and
throwafter
| return completionResponse.ConvertAll(c => new TextCompletionStreamingResult(c)); | ||
| } | ||
| catch (Exception e) when (e is not AIException && !e.IsCriticalException()) | ||
| catch (Exception e) when (e is not AIException) |
There was a problem hiding this comment.
MSIL for catch + when is way more costly than using the below. Apply the same for the others.
| catch (Exception e) when (e is not AIException) | |
| catch (AIException aiex) | |
| { | |
| throw; | |
| } | |
| catch (Exception ex) |
| catch (Exception ex) | ||
| { | ||
| nextStep.Observation = $"Error invoking action {nextStep.Action} : {ex.Message}"; | ||
| this._logger?.LogWarning(ex, "Error invoking action {Action}", nextStep.Action); |
There was a problem hiding this comment.
The exception is being swallowed and no log data is being stored about it.
LogWarning should be LogError or at least include the exception details.
There was a problem hiding this comment.
I will tag @lemillermicrosoft for input here.
The exception is being swallowed
As far as I know, this is expected behavior for StepwisePlanner, when it receives an exception, it will put details in Observation field and proceed to the next step.
LogWarning should be LogError
In case this is correct behavior, we shouldn't log it as error, because it doesn't break the application flow, instead it's just transient error. Previously we used Debug level here, and I updated it to Warning, and it's still not clear whether it was right choice.
or at least include the exception details.
As far as I can see, we include ex instance as first parameter to LogWarning method.
There was a problem hiding this comment.
Yes thank you @dmytrostruk . I think LogDebug is probably best in this scenario (I was gonna change in another PR).
| catch (Exception e) | ||
| { | ||
| this._logger?.LogError(e, "Something went wrong in system step: {0}.{1}. Error: {2}", targetFunction.SkillName, targetFunction.Name, e.Message); | ||
| return $"Something went wrong in system step: {targetFunction.SkillName}.{targetFunction.Name}. Error: {e.Message} {e.InnerException.Message}"; |
There was a problem hiding this comment.
| return $"Something went wrong in system step: {targetFunction.SkillName}.{targetFunction.Name}. Error: {e.Message} {e.InnerException.Message}"; | |
| return $"Something went wrong in system step: {targetFunction.SkillName}.{targetFunction.Name}. Error: {e.Message} {e.InnerException?.Message}"; |
| return await this._function(null, settings, context, cancellationToken).ConfigureAwait(false); | ||
| } | ||
| catch (Exception e) when (!e.IsCriticalException()) | ||
| catch (Exception e) |
There was a problem hiding this comment.
By removing the function IsCriticalException we are pratically considering any exceptions to be "critical" (should throw).
Two options:
- Remove all the catch block
- Keep the catch just to log and
throwafter
| } | ||
| } | ||
| catch (Exception e) when (!e.IsCriticalException()) | ||
| catch (Exception e) |
There was a problem hiding this comment.
By removing the function IsCriticalException we are pratically considering any exceptions to be "critical" (should throw).
Two options:
- Remove all the catch block
- Keep the catch just to log and
throwafter
| catch (Exception e) when (!e.IsCriticalException()) | ||
| catch (Exception e) | ||
| { | ||
| this.Logger.LogError(e, "Something went wrong in pipeline step {0}: {1}.{2}. Error: {3}", |
There was a problem hiding this comment.
| this.Logger.LogError(e, "Something went wrong in pipeline step {0}: {1}.{2}. Error: {3}", | |
| this._logger.LogError(e, "Something went wrong in pipeline step {0}: {1}.{2}. Error: {3}", |
| return parser(value, context.Culture); | ||
| } | ||
| catch (Exception e) when (!e.IsCriticalException()) | ||
| catch (Exception e) |
There was a problem hiding this comment.
By removing the function IsCriticalException we are pratically considering any exceptions to be "critical" (should throw).
Two options:
- Remove all the catch block
- Keep the catch just to log and
throwafter
| return converter.ConvertFromString(context: null, cultureInfo, input); | ||
| } | ||
| catch (Exception e) when (!e.IsCriticalException() && cultureInfo != CultureInfo.InvariantCulture) | ||
| catch (Exception) when (cultureInfo != CultureInfo.InvariantCulture) |
There was a problem hiding this comment.
By removing the function IsCriticalException we are pratically considering any exceptions to be "critical" (should throw).
Two options:
- Remove all the catch block
- Keep the catch just to log and
throwafter
|
Closing the PR due to a lack of consensus regarding the removal of the method. Additionally, it seems that the method can be useful in distinguishing between actionable and non-actionable exceptions. |

Motivation and Context
This PR is one of the follow-up PRs aimed at gradually replacing SK custom exceptions with SKException to provide a simple, consistent, and extensible exception model. You can find more details in the ADR discussing error handling.
Description
This PR removes the IsCriticalException extension method and updates all the code that used it. In a few cases, the change triggers the
CA1031 - Do not catch general exception typeswarning, which is temporarily suppressed to keep this PR focused on removing the IsCriticalException extension method. The proper fix for these cases will be applied by one of the following PRs dedicated to the fix.Contribution Checklist