Should a change in the type of thrown exceptions be considered a breaking change? - versioning

If I have a public API that is being managed using semantic versioning, should a change in the type of exceptions that a method may throw be considered a breaking change?
Consider this example:
// API version 1.0.0
public void Method()
{
// this may throw ThirdPartyComponentException
_thirdPartyComponent.SomeMethod();
}
Calling code may look like this:
try
{
_api.Method();
}
catch (ThirdPartyComponentException e)
{
//some recovery logic
}
If the implementation of API.Method is changed thusly:
// API version ?.?.?
public void Method()
{
try
{
// this may throw ThirdPartyComponentException
_thirdPartyComponent.SomeMethod();
}
catch (ThirdPartyComponentException e)
{
throw new MyApiException(e);
}
}
should the semantic version major value be incremented because this change may be breaking? It certainly would break the exception handler above so seems like a breaking change.

Related

Objectify 4 transactions

With Objectify 4 I am trying to throw a controlled exception inside a transaction. As vrun() interface does not allow throwing exceptions, I have to catch it. I do it, and then I want to perform the rollback, but when the transaction finishes and it all fails (I think it is because it tries to do a commit), not even doing the rollback. How can I do it?
Thanks in advance!
Code example:
ofy().transact(new VoidWork() {
#Override
public void vrun() {
//do something
//...
//find someting wrong and want to throw an exception
try {
throw new MyException(); //throw the exception
} catch (MyException e) {
ofy().getTransaction().rollback(); //catch it and perform rollback
}
}
});
//an error occurs

WCF/Silverlight: How can I foul a Channel?

I was told that I shouldn't cache channels in Silverlight/WCF because they may become faulted and unsuable. Can somone show me some sample code that would prove it can happen.
Call a service to prove the connection can work (i.e. no bogus URL)
Make a second call that fouls the channel by causing it to go into a faulted condition
Repeat the first call, which would fail.
In my own testing, the key is whether the binding you're using is session-oriented or not. If you're using a stateless binding like BasicHttpBinding, you can muck up the channel all you want and you're good. For instance, I've got a WCF service using the BasicHttpBinding that looks like this -- note specifically the Channel.Abort() call in SayGoodbye():
public class HelloWorldService : IHelloWorldService
{
public string SayHello()
{
return "Hello.";
}
public string SayGoodbye()
{
OperationContext.Current.Channel.Abort();
return "Goodbye.";
}
}
And the Silverlight client code looks like this (ugly as hell, sorry).
public partial class ServiceTestPage : Page
{
HelloWorldServiceClient client;
public ServiceTestPage()
{
InitializeComponent();
client = new HelloWorldServiceClient();
client.SayHelloCompleted += new EventHandler<SayHelloCompletedEventArgs>(client_SayHelloCompleted);
client.SayGoodbyeCompleted += new EventHandler<SayGoodbyeCompletedEventArgs>(client_SayGoodbyeCompleted);
client.SayHelloAsync();
}
void client_SayHelloCompleted(object sender, SayHelloCompletedEventArgs e)
{
if (e.Error == null)
{
Debug.WriteLine("Called SayHello() with result: {0}.", e.Result);
client.SayGoodbyeAsync();
}
else
{
Debug.WriteLine("Called SayHello() with the error: {0}", e.Error.ToString());
}
}
void client_SayGoodbyeCompleted(object sender, SayGoodbyeCompletedEventArgs e)
{
if (e.Error == null)
{
Debug.WriteLine("Called SayGoodbye() with result: {0}.");
}
else
{
Debug.WriteLine("Called SayGoodbye() with the error: {0}", e.Error.ToString());
}
client.SayHelloAsync(); // start over
}
}
And it'll loop around infinitely as long as you want.
But if you're using a session-oriented binding like Net.TCP or HttpPollingDuplex, you've got to be much more careful about your channel handling. If that's the case, then of course you're caching your proxy client, right? What you have to do in that instance is to catch the Channel_Faulted event, abort the client, and then recreate it, and of course, re-establish all your event-handlers. Kind of a pain.
On a side note, when it comes to using a duplex binding, the best approach that I've found (I'm open to others) is to create a wrapper around my proxy client that does three things:
(1) Transforms the obnoxious event-raising code generated by the "Add Service Reference" dialog box into a far-more-useful continuation-passing pattern.
(2) Wraps each of the events raised from the server-side, so that the client can subscribe to the event on my wrapper, not the event on the proxy client itself, since the proxy client itself may have to be deleted and recreated.
(3) Handles the ChannelFaulted event, and (several times, with a timeout) attempts to recreate the proxy client. If it succeeds, it automatically resubscribes all of its event wrappers, and if it fails, it throws a real ClientFaulted event which in effect means, "You're screwed, try again later."
It's a pain, since it seems like this is the sort of thing that should have been included with the MS-generated code in the first place. But it sure fixes a whole lot of problems. One of these days I'll see if I can get this wrapper working with T4 templates.

Exit Application On Error in a C # Library

It is a silly question I admit. So, apologies if this wastes your time but I just cannot find out a solution.
A WinForm Application which has a Class Library. I use Log4Net dll for logging information.
On Button_Click, I call a function in the Class Library which might throw an error. So, I have the contents of the function inside a try-catch-finally block. In the catch, I write log statements (using Log4Net dll).
Now, that an error has occurred, I want a Message to be shown to the UI. And after a Message is shown, I want it to quit.
How do I pass the control from the catch block of the Class Library back to the Form code so that I display a message and then quit?
Just call throw without any parameters after you've logged the error in the exception handler in the class library and it'll rethrow the exact same exception with the same callstack etc.
Then let your form catch it and handle it as you want.
In the Class Library Method, in the catch, rethrow the exception, so that it can bubble up to the form.
In the form Button_Click wrap the Class Method call in a try catch, and in the catch display the message and exit.
The library should probably re-throw the exception after logging about it.
class Form
{
OnClick()
{
try
{
library.Routine();
}
catch(Exception e)
{
// messagebox
// exit
}
}
}
class Library
{
public void Routine()
{
try
{
// stuff
}
catch(Exception e)
{
logger.error("error in routine", e);
throw;
}
}
}

Handing exception in BLL and return to client (either winforms or webforms)?

I am looking for the best way to do exception handling, for example.. when an error occurs in the business logic layer, is the best way to stop the METHOD using a catch and return an EVENT to the presentation layer?
What should this event contain?
Or should i always BUBBLE up exceptions and handle them in the presentation layer?
Anyone have some good links and required reading on this with regards to the best way of handling exceptions and how to handle them in the client ...
For example if i get a NullException in the BLL than i can catch this.. but whats the best way and return to the presentaiton layer and informing it of the issue..
Event? or another try / Catch in the presentation?
You can do several things;
Focus on improving the user experience when an unexpected error presents itself.
Always log errors either in eventlog or database.
Implement sufficient infrastructure to not let exceptions happen unless they are system exceptions.
Use throw instread of throw exception
Some links to help you:
http://today.java.net/pub/a/today/2003/12/04/exceptions.html
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
There are several ways to do it:
1) Throwing exceptions with describing message inside.
2) Firing events
3) Using special interfaces to interact with the user.For example you can implement something like IUiCallbacks interface and send the object, implementing this interface, to the BLL class or method. Later, method in BLL can call IUiCallbacks.SendMessage() or IUiCallbacks.SendError() to notify presentation. And you can have different classes, such as WinFormsUiCallbacks, WebFormsUiCallbacks and SilentUiCallbacks, implementing this interface.
I usually use 1) and 3)
Example of 3) as requested:
public interface IUiCallbacks
{
void SendMessage(string message);
void SendException(string message, Exception ex);
}
public class WinFormsUiCallbacks : IUiCallbacks
{
public void SendMessage(string message)
{
MessageBox.Show(message);
}
public void SendException(string message, Exception ex)
{
MessageBox.Show(string.Format("Unfortunately, the following errror has occurred:{0}{1}", Environment.NewLine, ex.Message));
}
}
public class OrderService
{
private IUiCallbacks _iUiCallbacks;
...
public OrderService() { ... }
public OrderService(IUiCallbacks iUiCallbacks)
{
_iUiCallbacks = iUiCallbacks;
}
...
public void AddOrder(Order order)
{
...
if(OrderAlreadyExists(order))
{
if(_iUiCallbacks != null)
_iUiCallbacks.SendMessage("The order can not be added, because it is already accepted.");
return;
}
...
}
...
}
So it can be used like this:
public partial class OrderForm : Form
{
...
public void btnAddOrderFromExcel_Click(...)
{
Order order = LoadOrderFromExcel(...);
OrderService orderService = new OrderService(new WinFormsUiCallbacks());
orderService.AddOrder(order);
}
...
}

How can I get the current exception in a WinForms TraceListener

I am modifying an existing WinForms app which is setup with a custom TraceListener which logs any unhandled errors that occur in the app. It seems to me like the TraceListener gets the message part of the exception (which is what gets logged), but not the other exception information. I would like to be able to get at the exception object (to get the stacktrace and other info).
In ASP.NET, which I am more familiar with, I would call Server.GetLastError to get the most recent exception, but of course that won't work in WinForms.
How can I get the most recent exception?
I assume that you have set an event handler that catches unhandled domain exceptions and thread exceptions. In that delegate you probably call the trace listener to log the exception. Simply issue an extra call to set the exception context.
[STAThread]
private static void Main()
{
// Add the event handler for handling UI thread exceptions
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
// Add the event handler for handling non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
...
Application.Run(new Form1());
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MyTraceListener.Instance.ExceptionContext = e;
Trace.WriteLine(e.ToString());
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
// similar to above CurrentDomain_UnhandledException
}
...
Trace.Listeners.Add(MyTraceListener.Instance);
...
class MyTraceListener : System.Diagnostics.TraceListener
{
...
public Object ExceptionContext { get; set; }
public static MyTraceListener Instance { get { ... } }
}
On the Write methods in MyTraceListener you can get the exception context and work with that. Remember to sync exception context.

Resources