How to catch CLR exception in my code block (C#) - c#

Here is my code:
private Message SendMessage(ref Message message, string serviceURL)
{
Message result = null;
try
{
IRequestChannel channel = null;
BasicHttpBinding binding = ...;
using (var cf = new ChannelFactory<IRequestChannel>(binding, new EndpointAddress(serviceURL)))
{
foreach (OperationDescription op in cf.Endpoint.Contract.Operations)
{
op.Behaviors.Remove<DataContractSerializerOperationBehavior>();
}
cf.Open();
channel = cf.CreateChannel();
channel.Open();
result = channel.Request(message);
channel.Close();
cf.Close();
channel = null;
}
binding = null;
}
catch (Exception ex)
{
Logger.LogError("Error parsing SOAP", ex.Message);
}
return result;
}
On line result = channel.Request(message);
I get an error posted below in a picture. However, I get it only when I turn "Break when" CLR exceptions occur. When I don't debug, my code doesn't go to the catch block.

Looks like you try serialize or deserialize string with value = 'X' to bool. I think you should check contract or check your message object.
Somewhere inside .net code calls XmlConvert.ToBoolean(String) method. Valid values for it 0 or 1 Link to doc

Related

BLE Read operation not working in view model for Xamarin forms

I'm trying to do BLE implementation in Xamarin forms. So I am able to connect and do write operation successfully but when I do read operation the app crashes. The read operation works in code behind that is xaml.cs but it crashes in viewmodel. This is exception I'm getting
Assertion at
/Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mono/mini/debugger-agent.c:4660,
condition is_ok (error)' not met, function:get_this_async_id, Could not execute the method because the containing type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder1[TReturn_REF]',
is not fully instantiated. assembly: type: member:(null) [libc] Fatal signal 6 (SIGABRT), code -1
(SI_QUEUE) in tid 24845 (twell.touchless), pid 24845 (twell.touchless)
This is my code in viewmodel
private async Task<string> ProcessDeviceInformationService(IService deviceInfoService)
{
try
{
await adapter.ConnectToDeviceAsync(device);
var sb = new StringBuilder("Getting information from Device Information service: \n");
var characteristics = await deviceInfoService.GetCharacteristicsAsync();
var characteristic = await deviceInfoService.GetCharacteristicAsync(Guid.Parse("00002A39-0000-1000-8000-00805F9B34FB"));
// characteristic.CanWrite = true;
//foreach (var characteristic in characteristics)
//{
try
{
if (Device.RuntimePlatform==Device.iOS)
{
characteresticnativedata = DependencyService.Get<ICharacteristiciOS>();
characteresticnativedata.OpeniosBluetooth(device);
}
if (characteristic != null)
{
var sbnew = new StringBuilder("BLE Characteristics\n");
byte[] senddata = Encoding.UTF8.GetBytes(string.IsNullOrEmpty(SendMessageLabel.Text) ? "0ab" : SendMessageLabel.Text);
if (MainThread.IsMainThread)
{
var newbytes = await characteristic.WriteAsync(senddata);
}
var charvalue = Characteristic.Value;
var bytes = await characteristic.ReadAsync();
string str = Encoding.UTF8.GetString(charvalue);
sbnew.AppendLine($"Characteristics found on this device: {string.Join(", ", str.ToString())}");
CharactericsLabel.Text = sbnew.ToString();
}
}
catch (Exception ex)
{
return ex.Message;
}
return CharactericsLabel.Text;
}
catch (Exception ex)
{
return ex.ToString();
}
}
This same code var bytes = await characteristic.ReadAsync(); works in xaml.cs but it crashes in viewmodel. I even used GetAwaiter().GetResult() instead of await. But still it crashes.
var bytes = characteristic.ReadAsync.GetAwaiter().GetResult();
I have no clue how to fix this any suggestions?

Exception while recieving the HttpResponseMessage in the client

I have created a self hosted WEB API, which works pretty well. While returning an object through HttpResponseMessage, I get an exception in the client code. Exception reads - "The underlying connection was closed: An unexpected error occurred on a receive." and the Message is "An error occurred while sending the request.". Kindly see attachment.
Client Code:
internal async Task<object> AddBuiltInAsync(string featureType, Dictionary<string, string> specAttr)
{
int rc = -1;
object returnedFeatureId = null;
try
{
FormUrlEncodedContent formContent = new FormUrlEncodedContent(specAttr);
string jsonSpecAttr = JsonConvert.SerializeObject(specAttr);
HttpResponseMessage response = await Client.PostAsync($"DWGImplODA/AddBuiltIn?featureType={featureType}&jsonSpecAttr={jsonSpecAttr}", formContent).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
object returnedFeatureId = await response.Content.ReadAsAsync<object>().ConfigureAwait(false);
// returnedFeatureId = JsonConvert.DeserializeObject<object>(jsonReturnedFeatureId);
}
else
{
_logger.Info("AddBuiltInAsync: Failed");
}
}
catch (Exception ex)
{
_logger.Error("AddBuiltInAsync: Exception - " + ex);
}
return returnedFeatureId;
}
Server Code:
[HttpPost]
public IHttpActionResult AddBuiltIn(string featureType, string jsonSpecAttr)
{
HttpResponseMessage response = null;
object returnedFeatureId = null;
string jsonReturnedFeatureId = string.Empty;
try
{
Dictionary<string, string> specAttr = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonSpecAttr);
integrationImpl = (IIntegrationImpl)cacheObject.Get("integrationImpl");
integrationImpl.AddBuiltIn(featureType, specAttr, out returnedFeatureId);
//jsonReturnedFeatureId = JsonConvert.SerializeObject(returnedFeatureId);
}
catch (System.Exception ex)
{
Console.WriteLine("AddBuiltIn Exception - ", ex.StackTrace);
}
return Ok(returnedFeatureId);
}
As an alternative I have also tried returning a json string.
However, controller fails to serialize the object(of a complex type Teigha.Runtime.RxClass) and returns nothing to the client. I am using json 6.0.0.0 for serialization and deserialization.
Any help would be nice.
Note: Not sure though, but I think previously I was able to return "Object" directly without using HttpResponseMessage or Json.

Microsoft.Azure.NotificationHub - Async call in sync method

I currently have to provide a sync as async method in my API: Please find the code below. The only problem is that I don’t have a
sync method in the backend. I use Azure.NotificationHub client. That client has only *Async methods. Is my way reasonable?
public PushHubNotificationResult SendPushMessage(string userId, string message)
{
PushHubNotificationResult result = new PushHubNotificationResult();
try
{
result = SendPushMessageAsync(userId, message).GetAwaiter().GetResult();
} catch (Exception ex)
{
result.Status = PushHubNotificationResultType.Error;
result.Error = ex.Message;
result.Exception = ex;
}
return result;
}
public async Task<PushHubNotificationResult> SendPushMessageAsync(string userId, string message)
{
PushHubNotificationResult result = new PushHubNotificationResult();
// EnableTestSend see: https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-push-notification-fixer/#self-diagnose-tips
// Create a new Notification Hub client.
Microsoft.Azure.NotificationHubs.NotificationHubClient hub =
Microsoft.Azure.NotificationHubs.NotificationHubClient.CreateClientFromConnectionString(NotificationHub, NotificationHubName);
// Sending the message so that all template registrations that contain "messageParam"
// will receive the notifications. This includes APNS, GCM, WNS, and MPNS template registrations.
Dictionary<string, string> templateParams = new Dictionary<string, string>();
templateParams["messageParam"] = message;
string userTag = "_UserId:" + userId; // That line sets the IMEI or SerialNo (WLAN only device) == userId to which the push message is sent
try
{
// Send the push notification and log the results.
NotificationOutcome outcome = await hub.SendTemplateNotificationAsync(templateParams, userTag);
result.Status = PushHubNotificationResultType.Success;
foreach (RegistrationResult hubResult in outcome.Results)
{
result.PushNotificationHub = hubResult.ApplicationPlatform;
result.RegistrationId = hubResult.RegistrationId;
result.Outcome = hubResult.Outcome;
}
}
catch (System.Exception ex)
{
result.Status = PushHubNotificationResultType.Error;
result.Error = ex.Message;
result.Exception = ex;
}
return result;
}
thanks for any advice,
Eric
If you want to use sync-over-async, it's very important that you use ConfigureAwait(false) in your async code, otherwise you are very likely to get a deadlock.
NotificationOutcome outcome =
await hub.SendTemplateNotificationAsync(templateParams, userTag).ConfigureAwait(false);
The async method already converts exceptions to PushHubNotificationResultType.Error, why does the sync version do it too?

Trapping Adwords errors in JScript when called from ClearScript?

Context: VS2015 Community; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0
For background on this posting, see an earlier posting (Kudos, by the way, to #BitCortex for solving the first conundrum.)
I now have a working Adwords mutation scripted in JScript via ClearScript and C#. The challenge now is to handle errors.
In the following chunk of code, I'm creating a new BudgetOrder:
var order = new BudgetOrder();
order.billingAccountId = acct.id;
order.startDateTime = "20160801 000000 Australia/Perth";
order.endDateTime = "20160831 235959 Australia/Perth";
var amt = new Money();
amt.microAmount = 10000000;
order.spendingLimit = amt;
var boo = new BudgetOrderOperation();
boo.operator = Operator.ADD;
boo.operand = order;
var mutations = ToTypedArray(BudgetOrderOperation, [boo]);
var response;
try {
response = bos.mutate(mutations);
Console.WriteLine(response.value[0].billingAccountId);
Console.WriteLine(response.value[0].id);
Console.WriteLine(response.value[0].lastRequest.status.ToString());
} catch (exc) {
Console.WriteLine(exc.message);
}
...
function ToTypedArray(typ, arr) {
var T;
if ("string" === typeof typ) {
T = host.type(typ);
} else {
T = typ;
}
var a = host.newArr(T, arr.length);
for (var i = 0; i < arr.length; i++) {
a.SetValue(arr[i], i);
}
return a;
}
The problem I'm having at the moment is that if there is an error, exc doesn't have anything useful in it apart from
exc
{...}
description: ""
message: ""
name: "Error"
number: -2146190593
for example, and response is undefined.
The usual data that would be available in a BudgetOrderReturnValue running natively in C# is not stored anywhere I can see.
I did try casting the result of the mutate using
response = host.cast(BudgetOrderReturnValue,bos.mutate(mutations));
but when the error occurs, response is still set as undefined.
I've been able to capture the XML for the mutate having specified
<add name="AdsClientLibs.DetailedRequestLogs" value="All" />
in App.config which gives me a detailed_logs.log in C:\Logs\Adwords. Thus when an error occurs I've been able to go back to that log and see what the error was, e.g.
<detail>
<ns2:ApiExceptionFault xmlns="https://adwords.google.com/api/adwords/cm/v201603" xmlns:ns2="https://adwords.google.com/api/adwords/billing/v201603">
<message>[BudgetOrderError.INVALID_BUDGET_DATE_RANGE # operations[0].operand.startDateTime.endDateTime; trigger:'Overlapping budget found']</message>
<ApplicationException.Type>ApiException</ApplicationException.Type>
<errors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:BudgetOrderError">
<fieldPath>operations[0].operand.startDateTime.endDateTime</fieldPath>
<trigger>Overlapping budget found</trigger>
<errorString>BudgetOrderError.INVALID_BUDGET_DATE_RANGE</errorString>
<ApiError.Type>BudgetOrderError</ApiError.Type>
<ns2:reason>INVALID_BUDGET_DATE_RANGE</ns2:reason>
</errors>
</ns2:ApiExceptionFault>
</detail>
However, none of that data seems to be available to the script.
Ideas, anyone?
LATER
var response;
var hostException;
var succeeded = host.tryCatch(
function () {
response = bos.mutate(mutations);
return true;
},
function (exception) {
hostException = exception;
return false;
});
if (succeeded) {
// process response
Console.WriteLine(response.value[0].billingAccountId);
Console.WriteLine(response.value[0].id);
Console.WriteLine(response.value[0].lastRequest.status.ToString());
} else {
// handle host exception
if (host.isType(BudgetOrderError, hostException)) {
Console.WriteLine("BudgetOrderException");
} else if (host.isType(ClientTermsError, hostException)) {
Console.WriteLine("ClientTermsError");
}
//...
}
Unfortunately, this doesn't work. The bos.mutate line causes the script to crash with an uncaught error.
NEXT DAY
The output from the EXE running the script:
Exception has been thrown by the target of an invocation.
at JScript global code (Script Document [temp]:149:0) -> var succeeded = host.tryCatch(
function () {
response = bos.mutate(mutations);
return true;
},
function (exception) {
hostException = exception;
return false;
})
The C# code
string script = File.ReadAllText(scriptSpec);
try
{
answer = JSengine.Evaluate(script);
}
catch (ScriptEngineException see)
{
Console.WriteLine(see.ErrorDetails);
ScriptEngineException next = see.InnerException as ScriptEngineException;
while (next != null)
{
Console.WriteLine(next.ErrorDetails);
next = next.InnerException as ScriptEngineException;
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
The JScript code as above. So the ClearScript engine appears not to be doing well with tryCatch.
A COUPLE OF DAYS LATER
I've learned one thing at least out of this: I don't need to put
WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging
into my C# code when instantiating the JScriptEngine object. If there's a debugger; statement in the script, I'll get prompted to start a debugging session.
But back to the script
debugger;
var CFG = new Config(Path.Combine(Settings.Item("EXEPath"), "mutator2.cfg"));
var config = new AdWordsAppConfig();
config.DeveloperToken = CFG.Retrieve("DeveloperToken");
config.UserAgent = CFG.Retrieve("UserAgent");
config.ClientCustomerId = CFG.Retrieve("CustomerID");
config.RetryCount = 10;
var user = new AdWordsUser(config);
user.OAuthProvider.ClientId = CFG.Retrieve("ClientId");
user.OAuthProvider.ClientSecret = CFG.Retrieve("ClientSecret");
//user.OAuthProvider.AccessToken = CFG.Retrieve("AccessToken");
user.Config.OAuth2RefreshToken = CFG.Retrieve("OAuth2RefreshToken");
try {
user.OAuthProvider.RefreshAccessToken();
} catch (ex) {
Console.WriteLine("RefreshAccessToken failed.");
Environment.Exit(1);
}
var bos = user.GetService(AdWordsService.v201603.BudgetOrderService);
bos = host.cast(BudgetOrderService, bos);
//bos.RequestHeader.clientCustomerId = config.ClientCustomerId;
//bos.RequestHeader.developerToken = config.DeveloperToken;
//bos.RequestHeader.userAgent = config.UserAgent;
bas = bos.getBillingAccounts();
var order = new BudgetOrder();
order.billingAccountId = CFG.Retrieve("BillingID");
order.startDateTime = "20160801 000000 Australia/Perth";
order.endDateTime = "20160830 000000 Australia/Perth";
var amt = new Money();
amt.microAmount = 10000000;
order.spendingLimit = amt;
var boo = new BudgetOrderOperation();
boo.operator = Operator.ADD;
boo.operand = order;
var mutations = ToTypedArray(BudgetOrderOperation, [boo]);
// bos.RequestHeader.validateOnly = true;
var response;
var hostException;
var succeeded = host.tryCatch(
function () {
response = bos.mutate(mutations);
},
function (exception) {
hostException = exception;
return true;
});
if (succeeded) {
// process response
Console.WriteLine(response.value[0].billingAccountId);
Console.WriteLine(response.value[0].id);
Console.WriteLine(response.value[0].lastRequest.status.ToString());
} else {
// handle host exception
if (host.isType(BudgetOrderError, hostException)) {
Console.WriteLine("BudgetOrderException");
} else if (host.isType(ClientTermsError, hostException)) {
Console.WriteLine("ClientTermsError");
}
//...
}
function qq(v, d) {
if (null === v) {
return "undefined" === typeof d ? "" : d;
} else {
return v;
}
}
function ToTypedArray(typ, arr) {
var T;
if ("string" === typeof typ) {
T = host.type(typ);
} else {
T = typ;
}
var a = host.newArr(T, arr.length);
for (var i = 0; i < arr.length; i++) {
a.SetValue(arr[i], i);
}
return a;
}
The first time through, it works fine. The second time through, with the dates unchanged, throws an AdWords error (date range already taken) which causes the JScriptEngine to throw an unhandled exception error. I get prompted to start a debugging session which on launch shows a dialog containing
Unhandled exception at line 52, column 2 in JScript - script block
0x8013baff - unknown exception
and the highlight on the line response = bos.mutate(mutations);. And this happens whether I've got a debugger; statement or not.
So I'm giving up on the scripting of AdWords using ClearScript. Maybe I should file this as a bug with the folk at ClearScript.
JScript has limited support for host exception handling, but you could try HostFunctions.tryCatch:
var hostException;
var succeeded = host.tryCatch(
function() {
response = bos.mutate(mutations);
},
function(exception) {
hostException = exception;
return true;
}
);
if (succeeded) {
// process response
...
}
else {
// handle host exception
if (host.isType(BudgetOrderError, hostException)) { ... }
else if (host.isType(ClientTermsError, hostException)) { ... }
...
}
Obviously for this to work you must expose the host exception types (BudgetOrderError et al) via ScriptEngine.AddHostType.

Target Invocation Exception in async method

I am trying to retrieve items from an rss feed but at times I get a TargetInvocationException 'unable to connect to remote server'. I am trying to use a try catch block to catch this error but I am not managing as I need the variable feed to be used throughout the other code and like this it is not visible. Any suggestions?
public static async Task<List<FeedItem>> getFeedsAsync(string url)
{
//The web object that will retrieve our feeds..
SyndicationClient client = new SyndicationClient();
//The URL of our feeds..
Uri feedUri = new Uri(url);
//Retrieve async the feeds..
try
{
var feed = await client.RetrieveFeedAsync(feedUri);
}
catch (TargetInvocationException e)
{
}
//The list of our feeds..
List<FeedItem> feedData = new List<FeedItem>();
//Fill up the list with each feed content..
foreach (SyndicationItem item in feed.Items)
{
FeedItem feedItem = new FeedItem();
feedItem.Content = item.Summary.Text;
feedItem.Link = item.Links[0].Uri;
feedItem.PubDate = item.PublishedDate.DateTime;
feedItem.Title = item.Title.Text;
try
{
feedItem.Author = item.Authors[0].Name;
}
catch(ArgumentException)
{ }
feedData.Add(feedItem);
}
return feedData;
}
}
}
This kind of error cannot be prevented. It is an exogenous exception.
There is only one way to deal with those kinds of errors: your application must be designed to expect them and react in a reasonable way (e.g., bring up an error dialog or notification).
In particular, don't try to ignore them with an empty catch block.
IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> feed;
//Retrieve async the feeds..
try
{
feed = await client.RetrieveFeedAsync(feedUri);
}
catch (TargetInvocationException e)
{
}

Categories