Reputation: 7994
As a general software concept, some async operation has the ability to take three different "paths":
In C# we can handle these 3 different "paths" like so:
try
{
await myService.doAsync();
}
catch(TaskCanceledException ex)
{
// Here, we know that somehow the Task was cancelled. Whether that is caused by something like
// a timeout or a user explicitly performed some operation to cancel the Task
// This might be apart of some actual business logic and so I want to handle it differently than
// a general exception
}
catch(Exception ex)
{
// This means something went wrong in the downstream code and I probably
// want to log an error and do something else or 'throw' again so upstream
// execution can handle the failure as well
}
However, trying to do this in JavaScript or TypeScript doesn't work as elegantly from what I have seen since we don't have the ability to check types which means we also can't cascade catch
blocks like we can in C#:
try
{
await myService.doAsync();
}
catch(e)
{
if(e instanceof TaskCancelledError) {
// Here, we know that somehow the Task was cancelled. Whether that is caused by something like
// a timeout or a user explicitly performed some operation to cancel the Task
// This might be apart of some actual business logic and so I want to handle it differently than
// a general exception
}else{
// This means something went wrong in the downstream code and I probably
// want to log an error and do something else or 'throw' again so upstream
// execution can handle the failure as well
}
}
class TaskCancelledError extends Error {
constructor() {
super("The task was cancelled");
}
}
Is what I laid out above the only way to achieve parity in features between TypeScript (JavaScript) and C#? I could do this, but it just felt a little hacky.
As a side note, would it be at all possible to change TypeScript to support this kind of structure of catch
blocks, but that TS would compile into the code we see above?
Upvotes: 2
Views: 197
Reputation: 43817
You are correct. That is the proper way to catch a specific type of exception in both Javascript and Typescript.
C# has a broad standard library with support for cancellation tokens and consistent use of TaskCanceledException. TypeScript does not. Those CancellationTokens have to be kept track of and it’s a fair amount of work. Many TypeScript async primitives (e.g. interval, fetch, xhr, etc.) support some kind of abort / cancel but they all do it in different ways and they don’t always throw at all.
It would be possible to change TypeScript to support this but I don’t think that will happen. There was discussion on it here and here bad they chose not to support this feature.
Upvotes: 2