I am using SignalR to send a message to my client. The way I am doing this is in a static function inside my hub file:
public static void CallTestFunction(int UserID, short TestParam)
{
try
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
hubContext.Clients.User(UserID.ToString()).TestFunction(TestParam);
}
catch (Exception ex)
{
Logger.LogError(ex);
}
}
This works prefectly fine. However, this does not throw error if I pass a random userID to this function like "123456789". What I want to do is something like:
public static void CallTestFunction(int UserID, short TestParam)
{
try
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
if(// Some sort of check like hubContext.Clients.User.Exists(UserID.ToString())
hubContext.Clients.User(UserID.ToString()).TestFunction(TestParam);
else
//Throw exception saying that user does not exist.
}
catch (Exception ex)
{
Logger.LogError(ex);
}
}
What do I do in the second code's if statement to make that code work?
Related
I'm currently writing test automation for a web based application for my company. I am utilising C#, Visual Studio test suite, and Selenium to perform testing.
Today I asked the question to my colleague of 'Is there any time where there is too many Try Catch blocks in code?'. His reply was to not work as I am at the minute (see example 1), but to just get the lower level try-catch to throw to the upper level try-catch so that the exception can be written there and the test failed (see example 2).
Example 1:
TestCase.cs
[TestMethod]
public void TestLogin()
{
Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
Console.WriteLine(#"Login Successful");
}
FW_Shared.cs
public static class FW_Shared
{
public static string OrgCode = "Test123";
public static string Username = "Tester";
public static string Password = "Password";
public static void Perform_Login(string OrgCode, string Username, string Password)
{
try
{
Driver.Url = "http://test.app.com/";
Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
Driver.FindElement(By.Id("username")).SendKeys(Username);
Driver.FindElement(By.Id("password")).SendKeys(Password);
Driver.FindElemenet(By.Id("btnsubmit)).Click();
}
catch (Exception ex)
{
Console.WriteLine(#"Error occurred logging on: " + ex.ToString());
return false;
}
return true;
}
}
Example 2
TestCase.cs
[TestMethod]
public void TestLogin()
{
try
{
Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
Console.WriteLine(#"Login Successful");
}
catch (Exception ex)
{
Console.WriteLine(#"Exception caught, test failed: " + ex.ToString());
Assert.Fail();
}
}
FW_Shared.cs
public static class FW_Shared
{
public static string OrgCode = "Test123";
public static string Username = "Tester";
public static string Password = "Password";
public static void Perform_Login(string OrgCode, string Username, string Password)
{
try
{
Driver.Url = "http://test.app.com/";
Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
Driver.FindElement(By.Id("username")).SendKeys(Username);
Driver.FindElement(By.Id("password")).SendKeys(Password);
Driver.FindElemenet(By.Id("btnsubmit)).Click();
}
catch (Exception)
{
throw;
}
return true;
}
}
Now I know that throwing the Exception to be caught is generally useless in typical coding as you want to handle specific exceptions that are returned, but I want to be able to catch any general web page or element issues so the test can fail on a general issue with the web application. For instance:
If the web page returns 503 or 404 issues
If an element is not present on the current web page
If an elements name has changed.
There is points in testing other, more complicated parts of the application that I handle unaccessible parts/elements with true/false bool returns and assert that, but since I am referencing multiple function across different classes would sticking with what I have be best, moving to top-level catching of all lower exceptions, or should I be doing something else?
I normally like to create a test helper method in its own class called "TestRunner.cs" which has a method in I use for all the tests which might throw an exception and I want to test the results of e.g.
public static Exception RunCodeThatMayThrowException(Action action)
{
try
{
action.Invoke();
return null;
}
catch (Exception ex)
{
return ex;
}
}
I can then just use the method like:
// Act
var actualException = TestRunner.RunCodeThatMayThrowExeption(() => {//some code});
// Assert
//Do some asserts
Your original Perform_Login method states no return parameter (‘void’) and always returns ‘true’ (unless there’s a crash) – these both hint that the method needs some re-factoring.
I would re-factor as follows, which isolates the calling code from the exception, makes the caller agnostic to any errors in the called method, and avoids a series of try-catches passing up the call stack (if your test had a try-catch in it then the production code that calls the method may well require the same):
Public Static Class FW_Shared
{
public static string OrgCode = "Test123";
public static string Username = "Tester";
public static string Password = "Password";
public static bool Perform_Login(string OrgCode, string Username, string Password)
{
Try
{
Driver.Url = "http://test.app.com/";
Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
Driver.FindElement(By.Id("username")).SendKeys(Username);
Driver.FindElement(By.Id("password")).SendKeys(Password);
Driver.FindElemenet(By.Id("btnsubmit)).Click();
}
Catch (Exception ex)
{
Console.WriteLine(#"Error occurred logging on: " + ex.ToString());
return false;
}
return true;
}
}
[TestMethod]
Public Void TestLoginSuccess()
{
Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
Console.WriteLine(#"Login Successful");
}
[TestMethod]
Public Void TestLoginFailure()
{
Assert.IsFalse(FW_Shared.Perform_Login(FW_Shared.OrgCode, “foo”, “bar”));
Console.WriteLine(#"Login Failed");
}
I have a global try/catch around my application methods to log unhandled exceptions and show an error message. For logging I use NLog. If I handle an exception and log it manually I set a key 'logged' in the exceptions data object to prevent the second log from the global try/catch.
public partial class App : Application
{
public static void Main(string[] args)
{
try
{
// Application stuff
SomeMethod();
}
catch (Exception ex)
{
if (ex.Data['logged'] == false)
{
logger.Error(ex, "A unhandled exception occured.")
ex.Data['logged'] = true;
}
// Show error dialog
}
}
public static void SomeMethod()
{
try
{
// Method stuff
}
catch (Exception ex)
{
logger.Error(ex, "A handled exception occured.")
ex.Data['logged'] = true;
throw;
}
}
}
I want to simplify the process so that I don't have to call ex.Data['logged'] = true; manually. Is there a way to modify the data property of an exception automatically while logging with NLog? I tried to use a MethodCall-Target but I had no access to the exception reference. The exception could only be passed as a string.
Would it work for you to use NLog to perhaps modify your approach to logging exceptions slightly?
public partial class App
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
public static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (Exception ex)
{
logger.ErrorEx(ex, "message");
}
}
public static void SomeMethod()
{
try
{
// Method stuff
}
catch (Exception ex)
{
logger.ErrorEx(ex, "A handled exception occured.");
throw;
}
}
}
public static class NLogExt
{
public static void ErrorEx(this NLog.Logger logger, Exception ex, string message)
{
if (ex.Data["logged"] as bool? == true) return;
logger.Error(ex, message);
ex.Data.Add("logged", true);
}
}
I am creating a utility class that will be used in my Facebook application for tasks that are commonly done, such as retrieving a Facebook Page ID from a URL. I am unsure if the below code is the correct way to throw and catch exceptions. Could someone please advise, thanks.
Utility Class:
public static class FacebookUtilities
{
public static string GetPageIDFromGraph(string pageUri, string accessToken)
{
try
{
FacebookClient client = new FacebookClient(accessToken);
dynamic result = client.Get(GetPageIDFromUri(pageUri), new { fields = "id" });
return result.ToString();
}
catch (FacebookOAuthException)
{
throw;
}
catch (FacebookApiException)
{
throw;
}
}
public static string GetPageIDFromUri(string pageUri)
{
if (pageUri.Contains('/'))
pageUri = pageUri.Substring(pageUri.LastIndexOf('/') + 1);
if (pageUri.Contains('?'))
return pageUri.Substring(0, pageUri.IndexOf('?'));
else
return pageUri;
}
}
Program class, just testing:
- Note "input" and "output" are just textboxes.
private void btnGetPageID_Click(object sender, EventArgs e)
{
try
{
output.Text = FacebookUtilities.GetPageIDFromGraph(input.Text, "Some Access Token Goes Here");
}
catch (FacebookOAuthException ex)
{
if (ex.ErrorCode == 803)
{
output.Text = "This page does not exist";
}
}
catch (FacebookApiException ex)
{
if (ex.ErrorCode == 100)
{
output.Text = "The request was not supported. The most likely cause for this is supplying an empty page ID.";
}
}
}
Is it correct to simply rethrow the exception from the utility class so that the calling class can catch it and do what needs to be done?
It seems that you do nothing with catched exceptions - so dont catch them. There are a lot of discussions about exception handling, but in general you should catch exceptions when you have something to do with them, or at least using finally to clean up resourses.
Since you aren't handling the exceptions in any way, your code can just be:
public static string GetPageIDFromGraph(string pageUri, string accessToken)
{
FacebookClient client = new FacebookClient(accessToken);
dynamic result = client.Get(GetPageIDFromUri(pageUri), new { fields = "id" });
return result.ToString();
}
You should only catch exceptions when you can meaningfully handle them, and it doesn't look like you can in your GetPageIDFromGraph method, so you should just propagate them.
I have a WCF service that I am consuming, and have been doing well so far.
However on our production system with a lot of traffic, I am noticing that that after gradual consistent rise and falls in memory (time in between gradually elongates and the delta gradually increases), the memory consumption is trending higher.
I'm wondering if it could be due to the way I am consuming the DAL web service:
For example:
public static int GetUserTypeFromProfileID(int profileID)
{
try
{
memberServiceClient = new MemberServiceClient(); // connect to the data service
return memberServiceClient.GetUserTypeFromProfileID(profileID); // get the profileID associated with the sessionID
}
catch (Exception ex)
{
ErrorLogging.Instance.Fatal(ex);
return 0;
}
}
If I changed this to the following, using a using statement:
public static int GetProfileIDFromSessionID(string sessionID)
{
try
{
using (memberServiceClient = new MemberServiceClient()) // connect to the data service
{
return memberServiceClient.GetProfileIDFromSessionID(sessionID); // get the profileID associated with the sessionID
}
}
catch (Exception ex)
{
ErrorLogging.Instance.Fatal(ex);
return 0;
}
}
Is it good form to perform the return inside the using section?
I believe there is nothing specific to WCF with using statement. It will dispose your MemberServiceClient before returning the value.
However Dispose() method on a WCF service client calls Close() method inside, which can throw exceptions. So it's better to call Close() method directly. You should also call Abort() method when exceptions occur. Here's the recommended implementation.
var result;
try
{
memberServiceClient = new MemberServiceClient();
result = memberServiceClient.GetUserTypeFromProfileID(profileID);
memberServiceClient.Close();
}
catch (FaultException e)
{
//handle exception
memberServiceClient.Abort();
}
catch (CommunicationException e)
{
//handle exception
memberServiceClient.Abort();
}
catch (TimeoutException e)
{
//handle exception
memberServiceClient.Abort();
}
Note: I have written a simple base class that handles these details. It's on NuGet.
Update:
Here's an example with WcfClientBase as requested:
public class MemberServiceManager : ServiceClientBase<MemberServiceClient>
{
public int GetUserTypeFromProfileID(int profileID)
{
//makes a call to GetUserTypeFromProfileID operation, closes the channel and handles the exceptions
//you may want to implement another base class for overriding exception handling methods
//return value will be default of return type if any exceptions occur
return PerformServiceOperation(item => item.GetUserTypeFromProfileID(profileID));
}
//or you can manually check if any exceptions occured with this overload
public bool TryGetUserTypeFromProfileID(int profileID, out int userType)
{
return TryPerformServiceOperation(item => item.GetUserTypeFromProfileID(profileID), out userType);
}
//these exception handling methods should be overriden in another common subclass
//they re-throw exceptions by default
protected override void HandleCommunicationException(CommunicationException exception)
{
Console.WriteLine(exception.Message);
}
protected override void HandleFaultException(FaultException exception)
{
Console.WriteLine(exception.Message);
}
protected override void HandleTimeoutException(TimeoutException exception)
{
Console.WriteLine(exception.Message);
}
}
You can also take a look at the source code on GitHub
I use wsDualHttpBinding in a wcf service, and i use the following code to store client channels:
public static void Subscribe()
{
try
{
// Subscribe the guest to the beer inventory
var guest = OperationContext.Current.GetCallbackChannel<ILoggingServiceCallBack>();
if (!CallbackList.Contains(guest))
{
CallbackList.Add(guest);
}
}
catch (Exception ex)
{
//do stuff
}
finally
{
//do stuff
}
}
and i call back clients like that:
public static void LoggingCallBack(Action<ILoggingServiceCallBack> callbackNotification)
{
try
{
if (OperationContext.Current != null)
{
var guest = OperationContext.Current.GetCallbackChannel<ILoggingServiceCallBack>();
if (!CallbackList.Contains(guest))
{
CallbackList.Add(guest);
}
}
foreach (var LoggingCallBack in CallbackList)
{
var temp = LoggingCallBack;
try
{
new Thread(() =>
{
try
{
callbackNotification(temp);
}
catch (Exception ex)
{
//do something
}
}).Start();
}
catch (Exception ex)
{
//do somethin
}
}
}
catch (Exception ex)
{
//doing something
}
finally
{
//doing something
}
}
im running through some troubles:
i have no way to tell if the client is online or not before i call
it back.
i need to be able to remove the client after no activity from the
list i guess i would be able to do that if i achieved number 1.
what is the best way to identify clients, in other words what is
the best unique identifier i can identify the client with?
if a connection with the client faulted i don't know how to detect
that and start new one from the client as if i tried to do that it refuse to and it throw exception that the connection is faulted.
sorry if i have asked more than one question, please give your opinion about the code i posted and any answer to any question of the above.