I'm about to start writing a .Net component which will be called from a VB COM+ service (the new component is a DLL which calls out to a webservice and returns based on the response). I'm not sure how to handle error conditions that might occur in the .Net code in the calling VB.
The two types of errors I'm worried about are:
exceptions that I might like to throw if a precondition is not met (e.g. the start date supplied as a parameter is less than 3 months after the end date supplied as a parameter; I might want to throw a StartDateNotValidException)
exceptions that are likely to happen as part of the webservice call (time out, 404 etc).
I'd like to return some specific feedback to the user and/or log some information to a log if either of these occur. I'd thought about returning Int return codes from the .Net code and avoiding Exceptions, but it's possible that the calling VB code may eventually be migrated to .Net, so I'd like to use Exceptions if possible.
I read on MSDN that COM Interop will automatically convert standard library exceptions to HRESULTs; has anyone had any experience using this? Could this be used to translate custom .Net exceptions to error conditions that I can handle in VB?
Thanks,
Nick
I am sure I have seen it done before, but it was in my previous job so I can't check the details. I think we inherited our exception classes from COMException and set the correct ErrorCode (which should be translated as HResult in unmanaged code). This is quite nice, because you can use HResult in unmanaged code as well as properly handle typed exception in managed client.
Please let me know if it actually works.
I ended up using the following method:
have a big Dictionary
that maps our application-specific
VB error codes to our
application-specific C# custom
exceptions
write a method that converts C# exceptions to VB error codes (and
vice-versa)
return an array of strings from the methods containing any business
exceptions that occurred in the
method call (there are only currently two of these)
The reason for doing this is that it was going to be too cumbersome to adapt our exception tree to extend COMException (more cumbersome than the above anyways). So, I never tried out inheriting from COMException and checking whether the ErrorCode got correctly converted to an HResult.
Thanks for the suggestion though, and apologies for not trying it out.
Related
I need to make a short premise: I am a software architect with more than 20 years of experience, not a junior asking directions. This is not to say "I know it all" (quite the contrary in fact) but just to give context and state that I have come across a legitimate doubt about something I thought was common knowledge and best practice and have done so for all this time.
I am working on different projects for different clients. I always check method's parameters for not being null and for other non valid states. A common precondition check you can find in my code is:
if (param == null) { throw new ArgumentNullException(nameof(param)); }
or
this.myField = myParam ?? throw new ArgumentNullException(nameof(myParam));
Also bear in mind that I use exceptions sparingly, I do not do user input validation with exceptions, I just use them to check and/or signal invalid states in the code, thus programming errors. It's extremely rare to find a try/catch block in my code at all.
One of my clients just asked me, without much margin to debate, to replace any similar occurrence with the use of custom exceptions. Meaning I am to define a CustomerNameArgumentNullException, CustomerNameFileNotFoundException, etc. and use those wherever I would use a standard exception.
Now I will comply, I have no right to debate the client request, but their lead programmer was pretty strong about this point on how this is the right way to go, that using default exceptions makes code less readable and also that custom exceptions make more easy to see what-is-what in Azure Application Insights. I tried to point out that he has the fully qualified name of the method that raised the exception so he can know which program, in which assembly and namespace and such but again, there was not much room to debate and it was not my place to do so.
So I've been wondering if he's actually right and I've been doing exceptions wrong all this time. If anyone has some more insight and/or some material I can read about that supports this theory.
Thanks.
While normally I'd suggest that a question like this should be closed as opinion-based, in this case there's really clear guidance from Microsoft:
Use the predefined .NET exception types
Introduce a new exception class only when a predefined one doesn't apply. For example:
Throw an InvalidOperationException exception if a property set or method call is not appropriate given the object's current state.
Throw an ArgumentException exception or one of the predefined classes that derive from ArgumentException if invalid parameters are passed.
In other words, your customer is asking you to go against guidance from the platform authors.
You may not be able to change the customer's mind to follow the guidance, but you can be confident that your approach is the recommended one, and their approach goes against that.
Following conventions like this is particularly important in Open Source projects - it's one thing to decide that you'll have your own conventions when only your team will work with the code, but if an application uses 10 different Open Source libraries, each of which has decided to create its own conventions, that's a nightmare.
There are two sides of the coin. Sure MS recommends this
Using custom exceptions gives you some advantages and disadvantages.
Advantages:
Abstraction
You can log telemetry data before you raise an exception. If not for custom exceptions, you'd have to catch an exception, log data and re-throw.
Customizing exception and error handling as needed by the app/services, etc
Disadvantages:
Telemetry data will have no stack trace if you are throwing custom exceptions.
Code maintenance and rigorous testing
There are various other things that come into picture, but catching an exception, logging metrics and then re-throwing (to preserve stack trace) the same exception is expensive.
Just my thoughts.
Hi i am using the vb6 code Logic in my application where i need to manage the error handling. In vb6 ADODB.Errors are used for capturing the exception.
I want to know the exception equivalent in vb.net for the Vb6 ADODB.Error codes
2147217885 (0x80040e23) A given HROW referred to a hard- or soft-deleted row.
2147217887 0x80040e21 Errors occurred
Can anyone please help to know the equivalent exception for the above two error codes
Have a look at This,
in particular the section on "Unhandled Errors in Event Handlers". It explains how to use the ADODB Errors collection in a try/catch block.
I don't think you're going to find a way to trap ADODB errors by using equivalent errors thrown in the .Net environment. There aren't one-to-one equivalencies between COM errors and .Net exceptions in general. What happens in this case with ADODB Error objects is that .Net uses interop marshaling to throw the error object into the catch block, wrapping it with the Exception object. You can evaluate the error there. However, the doc doesn't explain how you can iterate the Errors collection to see both of your errors. Perhaps you can post how that's done here once you've figured it out.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
For the software we're developing at the company that I work for, we use a third-party library which is developed by a guy that we're constantly in contact with. His code is written in C++, and we use C# in the project.
Normally, his library functions return error codes. I decided to have different exception classes to cover different ranges of error codes. For example, one exception class for parameter handling errors, one exception class for main operation errors, one exception class for input value errors and so on.
He thinks it's not a good idea, and suggests using one exception class for the library that catches all the errors, and then fetches the error code from an XML file and outputs the problem to the user. He thinks, it's pointless to write more than one exception class. And also he says that he can't promise that the error codes will be the same in different versions of the library.
I think it's a good idea to have more than one exception class because:
There may be different situations that we need to handle the problem differently. Maybe when there's a parameter exception, do other stuff than just outputting an error. But he thinks his library is handling everything, and we should just stop the operation and output an error. I also can't think of many concrete examples of cases we need to handle differently, other than showing an error message. But I feel we may need it, and I'm afraid that I'm just violating the YAGNI principle.
I think if he turns out wrong, and we need to handle things differently in different cases, I'll have to introduce conditional code (if error was A then do this, if B then do that). And it will be difficult to handle.
I think it's a better idea to develop the program in a way that we can handle different types of exceptions differently. But then the guy has much more experience than me, plus he has much more credibility in the company (I'm a new intern) and I'm pretty new to software development and I feel like maybe he's right and I'm just trying to add extra code because it looks pretty, and violating the YAGNI principle.
Do you think we should go with one class or more? And if you think we should use more than one exception class, what are your reasons?
If the error codes can change from version to version, then no amount of work (or lack of it) is going to save you trouble of having to remap these somehow at some point. If you have exceptions for codes (or code ranges) then it's hardly going to be much more work than if you didn't have, when error codes do change (you're going to be rearranging what exceptions are thrown, just as you would have to be jiggling the messages around for one exception if you didn't have dedicated classes).
Besides, in general practice, by .NET convention, you should create a dedicated exception class for specific exceptions that aren't aptly covered by BCL-provided exceptions (excluding use of the some in there that are meant for abstraction only).
For some Microsoft input, consider this:
Applications and libraries should not use return codes to communicate errors.
And this:
Consider throwing existing exceptions residing in the System
namespaces instead of creating custom exception types.
But, following the Exception Design Guidelines,
[will] help ensure that you use the existing
exceptions, where appropriate, and create new exceptions where they
add value to your library.
Stick to your guns.
You're right. It's better to use several exception classes for different types of errors (for different error codes). Exceptions are somewhat successors of error codes, so it's better to use exception. And the approach that guy is offering is again using error codes, wrapped by one exception class.
SqlException with his Number comes on my mind. It's a hell to catch different types of errors by checking error code.
You should definitely use more than one exception class. Note though that there are a ton of built in classes already made in the System namespace such as ArgumentNull and friends.
If you want to see a case where multiple exceptions aren't used, take a look at COM interop. It's a dark place with generic exceptions thrown and their reasoning being justified by a single integer HRESULT. Trust me, you don't want to recreate that.
One really specific use case though is for instance whenever you just want to catch a certain exception. i.e.
try
{
lib.OpenFile(mypath);
}catch(FileNotFoundException e)
{
//handle gracefully and possibly "ignore" this error
}
Here, you want to do some other action if the file isn't found. However, if OpenFile throws an exception because mypath is null, you probably want this exception to bubble up and throw an error. (at least so you can log it or something). With a single exception class, this becomes more painful
catch(MyException e)
{
if(e.Reason=10)
{
}else{
throw; //rethrow exception(which makes debugging more difficult)
}
}
If one has the following code:
data.SaveChanges();
(data is an ObjectContext)
The MSDN doc has listed the OptimisticConcurrencyException as thrown. That's fine but I known that a UpdateException can also be thrown (and possibly others too). How can I know which exceptions a method can throw?
I do not want to catch Exception as I only want to catch exceptions which I know I can handle in some way.
This is generally speaking - not just for the example above. There must be some way of knowing which exception a 'built-in' .NET method is throwing.
That's not a "native" method; it's an ordinary method that happens to be written by Microsoft rather than you.
Actual native methods cannot throw managed exceptions (although COM interop will convert things to managed exceptions)
Unlike Java, C# does not have exception specifications, so there is no inherent way of knowing what exceptions a method will throw.
Your only options are the documentation or a decompiler.
Just in case (sorry if it's obvious but there're guys who don't know it) you can hover your mouse over the class name / method call in your editor view in VS. It shows you all the exceptions that can be thrown by the method if defined in documentation.
I have a C# DLL being called from Excel VBA which I have exposed via a COM Callable Wrapper / COM Interop. I want to be able to pass any exceptions which occur in the C# code up onto the VBA client. Are there any recommended approaches to doing this ? Thanks.
It is possible to create your own exceptions that communicate HRESULT error codes back to VBA or other COM based callers. Here's an example that uses E_FAIL:
public class ComMessageException : Exception
{
public ComMessageException(string message)
:base(message)
{
HResult = unchecked((int)0x80004005);
}
}
Here is an MSDN article that describes the process.
This should give you the same VBA error support you had in VB6, it will display the error message of your choice to the user along with the HRESULT that you choose.
Years ago I have vague memories of returning error information on COM function calls. COM functions should not return exceptions. The fact that an error happened in the COM function is signalled by the return value. S_OK (0) meant success. negative numbers meant failure. You could use different negative numbers to pass basic error types, however for more specific error information, you had to implement the IErrorInfo interface on the COM object.
Having done this, Visual Basic 6 and Visual Studio 2000 handled COM errors nicely in Visual Basic, however older versions of VBA didnt.
If someone has used COM much more recently they may well be able to fill in the details, and correct where my memory has gone hazy over the years.
It strikes me that implementing a new COM wrapper code that translated exceptions into documented COM errors would not be an easy generic thing and that making a hand coded version could be done, but again, you would need to understand COM programming.
Redesigning your .NET objects so they reported error detail by calling your getlasterror() method in your object would be a sensible workaround.