Where to catch exceptions when using Task.ContinueWith? - exception

I would like to create an async method with Task that creates a file and immediately proceeds to executing next task which uploads created file to cloud.
Here is how this method looks:
public async TaskCreateAndUploadAsync()
{
await Task.Run(() =>
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
}
catch (Exception e)
{
//Log..
}
}).ContinueWith((result) =>
{
if (!result.IsFaulted)
{
try
{
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
}
});
}
My question is: Is the way how I catch exceptions in each Task individually correct or I should use one try-catch block around whole "Task..Task.ContinueWith"?

Where to catch exceptions when using Task.ContinueWith?
The proper answer is "don't use ContinueWith". For asynchronous code, you can use await instead; for synchronous code like this, you can just use nothing:
public async TaskCreateAndUploadAsync()
{
await Task.Run(async () =>
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
});
}
However, wrapping a method body in Task.Run like this is an antipattern; it's better to keep the method synchronous and have callers use Task.Run:
public void TaskCreateAndUpload()
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
}
From your method names, it sounds like some of them should be asynchronous. I/O is inherently asynchronous. So, if you have truly asynchronous I/O (i.e., not using Task.Run for fake-asynchrony), then your resulting method may look like this:
public async Task TaskCreateAndUploadAsync()
{
try
{
var _writeFile = new WriteFile(...);
await _writeFile.DoWorkAsync();
await storage.UploadCreatedObjectAsync(...);
}
catch (Exception e)
{
//Log..
}
}
Note the use of await instead of ContiueWith in this last example.

Related

Java 'throws' keyword in Dart

Im coming from a Java background where I use the throws keyword to lead an exception to the method calling another method. How can I do that I dart?
Method called:
void _updateCurrentUserEmail() async {
await FirebaseAuth.instance
.currentUser()
.then((FirebaseUser user) {
_email = user.email;
});
}
How it is called:
try {
_updateCurrentUserEmail();
} on Exception {
return errorScreen("No User Signed In!", barActions);
}
But it seems like the Exception is not caught, because I still get a NoSuchMethodException and the errorScreen is not shown.
While you correctly used try/catch, the exception is coming from an async function that you did not await.
try/catch only catch exceptions thrown within that block. But since you wrote:
try {
doSomethingAsyncThatWillTrowLater();
} catch (e) {
}
Then the exception thrown by the async method is thrown outside of the body of try (as try finished before the async function did), and therefore not caught.
Your solution is to either use await:
try {
await doSomethingAsyncThatWillTrowLater();
} catch (e) {
}
Or use Future.catchError/Future.then:
doSomethingAsyncThatWillTrowLater().catchError((error) {
print('Error: $error');
});
From the docs,
If the catch clause does not specify a type, that clause can handle any type of thrown object:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e'); <------------------
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
Change it to this:
try {
_updateCurrentUserEmail();
} on Exception catch(e){
print('error caught: $e')
}
Another way to handle error is to do the following:
void _updateCurrentUserEmail() async {
await FirebaseAuth.instance
.currentUser()
.then((FirebaseUser user) {
_email = user.email;
throw("some arbitrary error");
});
.catchError(handleError);
}
handleError(e) {
print('Error: ${e.toString()}');
}
If currentUser()’s Future completes with a value, then()’s callback fires. If code within then()’s callback throws (as it does in the example above), then()’s Future completes with an error. That error is handled by catchError().
Check the docs:
https://dart.dev/guides/libraries/futures-error-handling
Throw
Here’s an example of throwing, or raising, an exception:
throw FormatException('Expected at least 1 section');
You can also throw arbitrary objects:
throw 'Out of llamas!';
throwing an exception is an expression, you can throw exceptions in => statements, as well as anywhere else that allows expressions:
void someMethod(Point other) => throw UnimplementedError();
here is example
main() {
try {
test_age(-2);
}
catch(e) {
print('Age cannot be negative');
}
}
void test_age(int age) {
if(age<0) {
throw new FormatException();
}
}
hope it helps..

How to get Angularjs scope variable after reloadWithDebugInfo?

I have an angularjs web page and want to get the specified element's scope. But after executing the reloadWithDebugInfo function, the result is null;
private Page _page;
private Browser _browser;
private async void button1_ClickAsync(object sender, EventArgs e)
{
try
{
await initAsync();
await test2Async();
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message);
}
}
private async Task initAsync()
{
_browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false,
ExecutablePath = #"c:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
Timeout = 60000
});
}
private async Task test2Async()
{
try
{
_page = await _browser.NewPageAsync();
await _page.GoToAsync("https://SOME Angular JS WebPage");
await _page.EvaluateFunctionAsync(#"() => angular.reloadWithDebugInfo()");
var scopeContent = await _page.EvaluateFunctionAsync("() => angular.element(document.getElementsByClassName('left-column-v3')).scope() ");
// scopeContent is null. why? (the above javascript code runs successfully in the chrome dev console.)
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message);
}
}
These statements works well in chrome dev tools.
I expect the json content of the scope, but that is null;
Update:
sorry, I forgot something after Scope().
I want a variable in the scope, not scope itself:
var scopeContent = await _page.EvaluateFunctionAsync("() => angular.element(document.getElementsByClassName('left-column-v3')).scope().SomeVariable ");
The problem is that the result of the scope function is not serializable.
You would need to build a serializable object inside the EvaluateFunctionAsync and return that.

'System.IO.FileNotFoundException' after calling RfcommDeviceService.FromIdAsync(...)

I'm trying to make a function to connect to a specific Bluetooth device. I'm somewhat sure the DeviceInformation parameter is valid so the issue should be just contained to the function below. A short period of time after the line RfcommDeviceService.FromIdAsync(...) I will see A first chance exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.ni.dll in the Output in Visual Studio and then see The program '...' has exited with code -1 (0xffffffff).. Additionally, the exception is not being caught by try{} catch(Exception e){} so that might mean there is an issue elsewhere.
public async Task<bool> Connect(DeviceInformation deviceInformation)
{
try
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
rfcommService = await RfcommDeviceService.FromIdAsync(deviceInformation.Id);
});
System.Diagnostics.Debug.WriteLine("edfdshjkfdsklfdjslkf");
if (rfcommService == null)
{
return false;
}
System.Diagnostics.Debug.WriteLine(rfcommService.Device.ToString());
await streamSocket.ConnectAsync(
rfcommService.ConnectionHostName,
rfcommService.ConnectionServiceName);
dataReader = new DataReader(streamSocket.InputStream);
dataWriter = new DataWriter(streamSocket.OutputStream);
return true;
}
catch (Exception e)
{
Debug.WriteLine("Exception while connecting: " + e.Message);
Debug.WriteLine(e.StackTrace);
return false;
}
}
I also have the following Capabilities in Package.appxmanifest:
<Capabilities>
<Capability Name="internetClientServer" />
<DeviceCapability Name="proximity" />
<m2:DeviceCapability Name="bluetooth.rfcomm">
<m2:Device Id="any">
<m2:Function Type="name:serialPort" />
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
Turns out the DeviceInformation of making a Bluetooth connection is for WinRT desktop/tablet and not phone. The solution was to use a PeerInformation method.
The function now looks like the following:
public async Task<bool> Connect(PeerInformation peerInfo)
{
streamSocket = new StreamSocket();
try
{
await streamSocket.ConnectAsync(peerInfo.HostName, "{00001101-0000-1000-8000-00805f9b34fb}");
}
catch (System.Exception)
{
return false;
}
return true;
}
Writing can be done using await streamSocket.OutputStream.WriteAsync(rawMessage.AsBuffer());
. Reading I still haven't figured out how to do yet but the issue I was having with this question was resolved by the above.

Dart catch clause

I recently stumbled across the following Dart code:
void doSomething(String url, String method) {
HttpRequest request = new HttpRequest();
request.open(method, url);
request.onLoad.listen((event) {
if(request.status < 400) {
try {
String json = request.responseText;
} catch(e) {
print("Error!");
}
} else {
print("Error! (400+)");
}
});
request.setRequestHeader("Accept", ApplicationJSON);
}
I'm wondering what the e variable is in the catch clause:
catch(e) {
...
}
Obviously its some sort of exception, but (1) why do we not need to specify its type, and (2) what could I add in there to specify its concrete type? For instance, how could I handle multiple types of possible exceptions in a similar way to catchError(someHandler, test: (e) => e is SomeException)?
Dart is an optional typed language. So the type of e is not required.
you have to use the following syntax to catch only SomeException :
try {
// ...
} on SomeException catch(e) {
//Handle exception of type SomeException
} catch(e) {
//Handle all other exceptions
}
See catch section of Dart: Up and Running.
Finally catch can accept 2 parameters ( catch(e, s) ) where the second parameter is the StackTrace.

Dart try/catch clause unexpected behaviour

So I'm experimenting with a try/catch clause, and I don't understand why this is happening (normal or not):
void main() {
List someList = [1,2,3];
try {
for (var x in someList) {
try {
for (var z in x) {
}
} catch(e) {
throw new Exception('inside');
}
}
} catch(e) {
throw new Exception('outside');
}
}
So you see I'm trying to do a loop inside a loop, but on purpose, someList is not a List<List>, therefore the nested loop will throw an error ('inside' error) since 1 is an int, not a List.
That's the scenario, but what happens is it throws the 'outside' error.
Is this normal? If so, where did I go wrong?
The exception you're getting is because w is undefined. If you change w to someList, then you'll get an exception for x not having an iterator, like you expect. You'll then handle that "inside" exception and immediately throw another one, which you'll catch, and then you'll throw the "outside" one, which you don't handle and will see an error for. (This might make it look like you're getting an "outside" error, but the error started on the "inside".)
This might make things clearer:
void main() {
List someList = [1,2,3];
try {
for (var x in someList) {
try {
for (var z in x) { // This throws an exception
}
} catch(e) { // Which you catch here
print(e);
print("Throwing from inside");
throw new Exception('inside'); // Now you throw another exception
}
}
} catch(e) { // Which you catch here
print(e);
print("Throwing from outside");
throw new Exception('outside'); // Now you throw a third exception
}
} // Which isn't caught, causing an
// "Unhandled exception" message