Gurobi API Exceptions (GRBException) with IronPython - c#

I have a problem running a Gurobi Optimization Model using a C#/.NET library through IronPython.
I have a method to access variables though their name (ie GRBModel.GetVarByName), something like
public GRBVar variable(i,t)
{
try
{
GRBModel M = getModel();
string varname = varname(i,t);
GRBVar var = M.GetVarByName(varname);
return var;
}
catch (GRBException ex)
{
System.Console.WriteLine(ex.ToString());
throw new GRBException(ex.ToString());
}
}
The problem is that on my IronPython script, when I try to access a non existing variable, nothing happens... the message doesnt appear on the console. What I'm doing wrong???

I think you're missing a return statement somewhere; if you catch the exception, the method does not return. (Doesn't the C# compiler error in that case?)
If this method is just for IronPython, you could just let the exception pass through to IronPython and deal with it there.

According to this page in the Gurobi .NET Reference Manual, GRBException inherits from the .NET Exception class. To obtain the error message from an Exception based class you should use the Message property rather than the ToString() method, which by default normally displays only the class name for reference classes.
In other words, change the catch clause to:
catch (GRBException ex)
{
System.Console.WriteLine(ex.Message);
}
Alternatively, you could output the ErrorCode property which is specific to the GRBException class.

Related

How do you test for the specific reason an exception was thrown?

What is the correct way to determine exactly what caused an exception, to correct it?
Consider the code below. I attempt to parse a string of XML, but occasionally, the incoming XML will not be top-level, meaning it needs to be surrounded by a root element.
Which this happens, the parser throws an XmlException, but it could throw that for a lot of reasons. I want to catch this one specific reason.
I do this, which I concede is probably not great:
var doc = new XmlDocument();
try
{
doc.LoadXml(xml);
}
catch(XmlException e)
{
if(e.Message.Contains("multiple root elements"))
{
doc.LoadXml($"<root>{xml}</root>");
}
else
{
throw e;
}
}
This feels like a hack. What is the correct way to do this?
There is a new feature of C# that allows you to filter exceptions in the catch clause with when keyword:
try
{
}
catch (XmlException ex) when ( ex.Message.Contains(...) )
{
//handle
}
You can use multiple fields to recognize the exception type, like the InnerException, StackTrace, and Data. As #David Hruška suggests, the HResult property is also a good place to check to recognize the type of the exception
The Message is not the best property to use for the check, as it is usually localized for the built-in types and as a result might look different with other culture setting.
you can try to make a switch for XmlException.HResult as described here:
https://msdn.microsoft.com/en-us/library/system.xml.xmlexception(v=vs.110).aspx
The only thing I am not sure, if it points the the specific exception type (like XmlException) or specific exception "message".
If this does not help, I think you have no other option than checking for message.
EDIT: Also, as was pointed above, you should throw; instead of throw e; as the second clears the StackTrace. ReSharper also warns about this one.
There are multiple ways to achieve what you're trying to do.
Different test frameworks bring their own tools to help with this too.
For example, if you're using MSVS Test Framework, the simplest option is to only check for the exception type. In this case you just mark the test method with "ExceptedExceptionAttribute" and specify the expected exception type to be thrown from the method, as follows:
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Action_ThrowsException()
{
// test logic here
}
There is another constructor available, which allows to specify the exact exception message as the second parameter, which is rarely used. You can find the documentation for ExpectedExceptionAttribute in MSDN.
Another option, where you have more control, would be what was already suggested in the other answers, which can be encapsulated in a helper method as follow:
private static T Throws<T>(Action action) where T : Exception
{
try
{
action();
Assert.Fail();
}
catch (T ex)
{
// This exception was expected.
return ex;
}
}
Using this helper method, you now can have your test method as follows:
[TestMethod]
public void Action_ThrowsException()
{
// test logic here
ArgumentException aex = Throws<ArgumentException>(()=>{
// Test logic here
});
Assert.AreEqual("Expected error message", aex.Message);
}
As you can see, this option provides you with higher flexibility as you can now validate other aspects of the exception explicitly.
FYI: The second solution is given as part of the xUnit framework.

Detecting when a DLL has raised an exception

OK, so I have the C# DLL method:
public void DeletePublisher(string strName)
{
try
{
if (_PublisherData.PublisherDictionary.ContainsKey(strName))
_PublisherData.PublisherDictionary.Remove(strName);
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
}
It works fine. If there is a exception it is detected and added to the log.
At the moment, the above is called via MFC in my C++ project using a wrapper:
bool CMSATools::DeletePublisher(CString strPublisher)
{
bool bDeleted = false;
if (m_pInterface != nullptr)
{
CComBSTR bstrPublisher = strPublisher.AllocSysString();
throw_if_fail(m_pInterface->DeletePublisher(bstrPublisher));
bDeleted = true;
}
return bDeleted;
}
They both work fine. The issue is that fact that the CPP method currently has no knowledge of the C# method having failed. Now, in this particular instance I know I could change the signature of the DLL method to return false for a exception failure occurring and examine that return value in the CPP file.
But, in other instances I am already using the return value and thus, it would seem for consistency to me, that I pass in a bool bExceptionRaised parameter instead to my methods in the DLL.
That way, I can test that value when the method seemed to complete and if it is false act accordingly.
At the moment my application doesn't realise that an exception occurred and that is confusion.
Can I assume that either of these methodologies are the simplest approach to what I am trying to detect?
Update
Based on the answer provided I have tried to follow this tutorial and I am getting confused. I have tried to follow it and I can't create a CLR DLL and build it that is a bridge to my C# DLL file.
Whilst I appreciate the answer I feel like it is breaking up everything I have worked on since the C# DLL already handles and logs it's exceptions. Whilst I would like to learn how to build this bridge for the future, I still think perhaps at the point in time just changing my signatures is sufficient. Either way, my attempt a basic build of a bridge is failing.
Use a C++/CLI wrapper for the access of the managed component.
With C++/CLI you can directly use the C# component can catch the managed exception and you can throw a native exception or even return true or false... whatever you want.
void DoManagedStuff(SOMEDATA somedata)
{
try
{
auto sm = ConvertToSomeDataToManaged(somedata);
CallManagedCode(sm);
}
catch (Exception^ e)
{
throw CMyNativeException();
}
}

How to pass exception message from DLL to main application

Let's say that I have a class in my dll file:
public ClassInDllFile()
{
String str = "";
try
{
str = someClassMethod();
}
catch (Exception e) // or more precised exception type
{
// some code
}
}
I don't want to put exception message in MessageBox from Dll level (it requires additional references), but I would to pass it to some (on example) WinForm application.
You can just catch the exception in the WinForms class.
This means you should not catch the exception here, but in the WinForms class itself, where you can show a dialog.
You could use something like (I changed a bit of code from your example to improve naming):
public ClassInDllFile()
{
# Other functions
///
/// Might throw a ... exception
///
public Run()
{
String str = someClassMethod(); # Might cause an exception
# More code
}
And in your WinForms class:
var instance = ClassInDllFile()
try
{
instance.Run()
}
catch (Exception e) // or more precised exception type
{
// Error handling code
}
# More code
Also it is a good idea to document the ClassInDllFile.Run function which type of exceptions it might generate to inform calling functions to act upon it.
There are several ways in which you could handle this.
One simple way is to just throw the exception, and handle it in the outer / calling class.
Another is to gather info from the exception in your catch clause (like ExceptionMessage, StackTrace, and perhaps InternalException), and store these in properties that the the calling class can check. You might then also include a boolean property like Suceeded, which you set to false if an exception occurs. Then the calling class can check that property after making the call, and retrieve more details about the exception if it needs them.
You can manipulate this however you want. Experiment until you find a solution that fits your needs.

Unit testing with entlib - excluding catches

I've got a method that does some IO that generally looks like this:
public bool Foo()
{
try
{
// bar
return true;
}
catch (FileNotFoundException)
{
// recover and complete
}
catch (OtherRecoverableException)
{
// recover and complete
}
catch (NonRecoverableException ex)
{
ExceptionPolicy.HandleException(ex, "LogException");
return false;
}
}
The method isn't mission critical to be completed, there are external recovery steps - and it's relatively common for NonRecoverableException to be thrown - it's in the spec for it to return false, report 'cannot be completed at this time' and processing moves along. A NonRecoverableException does not put the program in an invalid state.
When I'm unit testing, and one of these exceptions is thrown, I get the error that
Activation error occured while trying to get instance of type ExceptionPolicyImpl
And I'd like to suppress that in favor of getting the actual/original exception information instead of EntLib not being able to log (and, indeed to force the NonRecoverableException and have an [ExpectedException(typeof(NonRecoverableException))] unit test to ensure that this method complies with the spec.
How might I go about that?
edit
Using preprocessor directives is not ideal as I hate seeing test-specific code in the codebase.
Testability of your code using the Entlib static facades is difficult. Without changing your code a little, your only answer is to add an app.config file to your test assembly and set up the Entlib exception block with an innocuous policy that does nothing.
However, in Entlib 4 (and 5, which I see you're using) there's another way. We added an instance entry point to all the blocks specifically to improve the testability story. For the exception block, that instance is the ExceptionManager. Using it is pretty simple. Get an exception manager instance into your type, and then call it instead of ExceptionPolicy. Something like this:
public class Whatever {
private ExceptionManager exm;
public Whatever(ExceptionManager exm) { this.exm = exm; }
public bool Foo() {
try {
... do whatever ...
}
catch(NonRecoverableException ex) {
exm.HandleException(ex, "LogException");
return false;
}
}
}
Now that you've got that in there, you can mock out the ExceptionManager (it's an abstract base class) to essentially no-op it during test, either manually or using a mock object framework.
If you don't want to force your users to use a DI container, you can add a default constructor that gets the current exception manager:
public class Whatever {
private ExceptionManager exm;
public Whatever() : this(EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>()) { }
public Whatever(ExceptionManager exm) { this.exm = exm; }
}
End users use the default constructor, your tests use the one that takes in an explicit ExceptionManager, and you have your hook to mock out anything Entlib uses.
All the blocks now have these "Manager" classes (where they make sense, anyway).
Hmm, you could refactor the code to place everything in the try block in a separate method and configure you tests to call that instead of the existing method?

GetGlobalResourceObject exception handling

I have a project that makes extensive use of the GetGlobalResourceObject which is a member of the System.Web.UI class. It works fine providing english or french labels to the bilingual C#/ASP.NET application.
But....if the reference in the resource file is missing or malformed the application crashes
There are hundreds of calls like this
GetGlobalResourceObject("XXX.WebResource", "Remove")
Is there any way to encapsulate the GetGlobalResourceObject with an exception handler so that it returns null and logs it if there's a problem without adding a try/catch to each call?
I am new to C# so I don't know if I can override the GetGlobalResourceObject with my own class and then do a search and replace. Surely there is a better way.
Kevinsky
You can write your own version of GetGlobalResourceObject to embed the exception handling and logging in that:
public static Object MyGetGlobalResourceObject (string classKey,
string resourceKey)
{
try
{
return GetGlobalResourceObject (classKey, resourceKey);
}
catch (MissingManifestResourceException ex)
{
// log error
return null;
}
}
This code is provided as an starting point
You could even write it as an extension method on HttpContext.
You will have to do a global search and replace to call this rather than the base method, which isn't the most elegant solution, but it will work.

Categories

Resources