As a general software concept, some async operation has the ability to take three different "paths":
- The operation successfully worked and we continue execution
- The operation failed and the system threw an exception
- The operation was cancelled by either the system (a timeout) or by user interaction
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?