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

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.

Related

Why HttpClient.GetFromJsonAsync doesn't throw an exception when the response is HTML instead of JSON?

I'm learning Blazor.
I have created a Blazor WASM App with the "ASP.NET Core Hosted" option.
So I have 3 projects in the solution: Client, Server and Shared.
The following code is in the Client project and works perfectly when the endpoint is correct (obviously). But at some point I made a mistake and messed up the request URI, and then I noticed that the API returned an HTML page with code 200 OK (as you can see in the Postman screenshot below the code).
I expected one of my try-catches to get this, but the debugger jumps to the last line (return null) without throwing an exception.
My first question is why?
My second question is how can I catch this?
I know fixing the endpoint fixes everything, but would be nice to have a catch that alerts me when I have mistyped an URI.
Thanks.
private readonly HttpClient _httpClient;
public async Task<List<Collaborator>> GetCollaborators()
{
string requestUri = "api/non-existent-endpoint";
try
{
var response = await _httpClient.GetFromJsonAsync<CollaboratorsResponse>(requestUri);
if (response == null)
{
// It never enters here. Jumps to the last line of code.
}
return response.Collaborators;
}
catch (HttpRequestException)
{
Console.WriteLine("An error occurred.");
}
catch (NotSupportedException)
{
Console.WriteLine("The content type is not supported.");
}
catch (JsonException)
{
Console.WriteLine("Invalid JSON.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return null;
}
it is a never good idea to use GetFromJsonAsync, You are not the first who are asking about the strange behavior. Try to use GetAsync. at least you will now what is going on.
var response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<CollaboratorsResponse>(stringData);
... your code
}
else
{
var statusCode = response.StatusCode.ToString(); // HERE is your error status code, when you have an error
}

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..

Future.wait() not catching exceptions (Dart)

In my Flutter app I'd like to make multiple network calls simultaneously and then do something when they all have finished. For this I use Future.wait(), which does what I want. However when a call fails it throws an exception, which is somehow not caught in the exception handler (i.e. uncaught exception).
When I do await _fetchSomeData() separately (outside Future.wait()) the exception does get called by the exception handler as expected.
Future<bool> someMethod() async {
try {
var results = await Future.wait([
_fetchSomeData(),
_fetchSomeOtherData()
]);
//do some stuf when both have finished...
return true;
}
on Exception catch(e) {
//does not get triggered somehow...
_handleError(e);
return false;
}
}
What do I need to do to catch the exceptions while using Future.wait()?
Update:
I have narrowed down the issue. Turns out if you use another await statement in the method that is called by the Future.wait() it causes the issue. Here an example:
void _futureWaitTest() async {
try {
//await _someMethod(); //using this does not cause an uncaught exception, but the line below does
await Future.wait([ _someMethod(), ]);
}
on Exception catch(e) {
print(e);
}
}
Future<bool> _someMethod() async {
await Future.delayed(Duration(seconds: 0), () => print('wait')); //removing this prevents the uncaught exception
throw Exception('some exception');
}
So if you either remove the await line from _someMethod() or if you just call _someMethod() outside of Future.wait() will prevent the uncaught exception. This is most unfortunate of course, I need await for an http call... some bug in Dart?
I have the Uncaught Exceptions breakpoints enabled. If I turn this off the issue seems to be gone. Perhaps it's an issue with the debugger. I am using Visual Studio Code and the latest flutter.
What do I need to do to catch the exceptions while using Future.wait()?
What I found out when I used the same code as you the code inside of each procedure which is used in Future.wait() must be wrapped with try/catch and on catch must return Future.error(). Also eagerError must be set to true.
try {
await Future.wait([proc1, ...], eagerError: true);
} on catch(e) {
print('error: $e')
}
/// Proc 1
Future<void> proc1() async {
try {
final result = await func();
} on SomeException catch(e) {
return Future.error('proc 1 error: $');
}
}
I think you are a bit mislead by the Future.wait() naming. Future.wait() returns another future that will have a List of elements returned by each future when it completes with success.
Now since the Future.wait() is still a future. You can handle it in two ways:
Using await with try catch.
Using onError callback.
Tis will be something like
Future.wait([futureOne, futureTwo])
.then((listOfValues) {
print("ALL GOOD")
},
onError: (error) { print("Something is not ok") }

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.

Is there any way within middleware running on ASP.NET Core 2.2 to detect if the request is for an ApiController?

I have an application with both MVC and 'new' ApiController endpoints in ASP.NET Core 2.2 co-existing together.
Prior to adding the API endpoints, I have been using a global exception handler registered as middleware using app.UseExceptionHandler((x) => { ... } which would redirect to an error page.
Of course, that does not work for an API response and I would like to return an ObjectResult (negotiated) 500 result with a ProblemDetails formatted result.
The problem is, I'm not sure how to reliably determine in my 'UseExceptionHandler' lambda if I am dealing with an MVC or a API request. I could use some kind of request URL matching (eg. /api/... prefix) but I would like a more robust solution that won't come back to bite me in the future.
Rough psuedo-code version of what I'm trying to implement is:
app.UseExceptionHandler(x =>
{
x.Run(async context =>
{
// extract the exception that was thrown
var ex = context.Features.Get<IExceptionHandlerFeature>()?.Error;
try
{
// generically handle the exception regardless of what our response needs to look like by logging it
// NOTE: ExceptionHandlerMiddleware itself will log the exception
// TODO: need to find a way to see if we have run with negotiation turned on (in which case we are API not MVC!! see below extensions for clues?)
// TODO: ... could just use "/api/" prefix but that seems rubbish
if (true)
{
// return a 500 with object (in RFC 7807 form) negotiated to the right content type (eg. json)
}
else
{
// otherwise, we handle the response as a 500 error page redirect
}
}
catch (Exception exofex)
{
// NOTE: absolutely terrible if we get into here
log.Fatal($"Unhandled exception in global error handler!", exofex);
log.Fatal($"Handling exception: ", ex);
}
});
});
}
Any ideas?
Cheers!
This might be a bit different than what you expect, but you could just check if the request is an AJAX request.
You can use this extension:
public static class HttpRequestExtensions
{
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
if (request.Headers == null)
return false;
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
}
And then middleware with an invoke method that looks like:
public async Task Invoke(HttpContext context)
{
if (context.Request.IsAjaxRequest())
{
try
{
await _next(context);
}
catch (Exception ex)
{
//Handle the exception
await HandleExceptionAsync(context, ex);
}
}
else
{
await _next(context);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
//you can do more complex logic here, but a basic example would be:
var result = JsonConvert.SerializeObject(new { error = "An unexpected error occurred." });
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
return context.Response.WriteAsync(result);
}
see this SO answer for a more detailed version.
If you want to check whether the request is routed to ApiController, you could try IExceptionFilter to hanlde the exceptions.
public class CustomExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (IsApi(context))
{
HttpStatusCode status = HttpStatusCode.InternalServerError;
var message = context.Result;
//You can enable logging error
context.ExceptionHandled = true;
HttpResponse response = context.HttpContext.Response;
response.StatusCode = (int)status;
response.ContentType = "application/json";
context.Result = new ObjectResult(new { ErrorMsg = message });
}
else
{
}
}
private bool IsApi(ExceptionContext context)
{
var controllerActionDesc = context.ActionDescriptor as ControllerActionDescriptor;
var attribute = controllerActionDesc
.ControllerTypeInfo
.CustomAttributes
.FirstOrDefault(c => c.AttributeType == typeof(ApiControllerAttribute));
return attribute == null ? false : true;
}
}
Thanks to all of the advice from others, but I have realised after some more thought and ideas from here that my approach wasn't right in the first place - and that I should be handling most exceptions locally in the controller and responding from there.
I have basically kept my error handling middleware the same as if it was handling MVC unhandled exceptions. The client will get a 500 with a HTML response, but at that point there isn't much the client can do anyway so no harm.
Thanks for your help!