[Mono-bugs] [Bug 572630] New: AsyncCompletedEventArgs.Error always null when handling SmtpClient.SendCompleted

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Thu Jan 21 06:26:10 EST 2010


http://bugzilla.novell.com/show_bug.cgi?id=572630

http://bugzilla.novell.com/show_bug.cgi?id=572630#c0


           Summary: AsyncCompletedEventArgs.Error always null when
                    handling SmtpClient.SendCompleted
    Classification: Mono
           Product: Mono: Class Libraries
           Version: 2.6.x
          Platform: All
        OS/Version: Ubuntu
            Status: NEW
          Severity: Normal
          Priority: P5 - None
         Component: System
        AssignedTo: mono-bugs at lists.ximian.com
        ReportedBy: dpldobrev at yahoo.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---
           Blocker: ---


Created an attachment (id=337950)
 --> (http://bugzilla.novell.com/attachment.cgi?id=337950)
Contributed under the MIT license; explained in "Additional Information"

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 6.1; bg; rv:1.9.1.7)
Gecko/20091221 Firefox/3.5.7

When sending an asynchronous e-mail with SmtpClient.SendAsync and handling
SmtpClient.SendCompletedd, the Error property of the AsyncCompletedEventArgs
object in the event handler is always null. However, it should be null only if
there was no error (that is, the e-mail was successfully sent). Otherwise
AsyncCompletedEventArgs.Error should contain the exception that occurred.

Reproducible: Always

Steps to Reproduce:
1. Add an event handler for the SmtpClient.SendCompleted event;
2. Deliberately configure the SmtpClient object (host, port, etc.) incorrectly;
3. Try to send an e-mail using SmtpClient.SendAsync;
Actual Results:  
The sending of the e-mail is not successful and the Error property of the
AsyncCompletedEventArgs object in the handler is null.

Expected Results:  
The sending of the e-mail is not successful and the Error property of the
AsyncCompletedEventArgs object in the handler contains the error that occurred.

The problem is in the SmtpClient.SendAsync method. It uses a BackgroungWorker
which internally catches any exceptions thrown by its OnDoWork method:

void ProcessWorker (object argument, AsyncOperation async, SendOrPostCallback
callback)
        {
            // do worker
            Exception error = null;
            DoWorkEventArgs e = new DoWorkEventArgs (argument);
            try {
                OnDoWork (e);
            } catch (Exception ex) {
                error = ex;
                e.Cancel = false;
            }
            callback (new object [] {
                new RunWorkerCompletedEventArgs (
                    e.Result, error, e.Cancel),
                async});
        }

However, SmtpClient.SendAsync also catches any exceptions in its handler for
DoWork:

public void SendAsync (MailMessage message, object userToken)
        {
            if (worker != null)
                throw new InvalidOperationException ("Another SendAsync
operation is in progress");

            worker = new BackgroundWorker ();
            worker.DoWork += delegate (object o, DoWorkEventArgs ea) {
                try {
                    user_async_state = ea.Argument;
                    Send (message);
                } catch (Exception ex) {
                    ea.Result = ex;
                }
            };
            worker.WorkerSupportsCancellation = true;
            worker.RunWorkerCompleted += delegate (object o,
RunWorkerCompletedEventArgs ea) {
                // Note that RunWorkerCompletedEventArgs.UserState cannot be
used (LAMESPEC)
                OnSendCompleted (new AsyncCompletedEventArgs (ea.Error,
ea.Cancelled, user_async_state));
            };
            worker.RunWorkerAsync (userToken);
        }

Thus, the thrown exception never reaches BackgroungWorker.ProcessWorker which
causes the local variable of "error" to always equal null, and the
RunWorkerCompletedEventArgs always receives null for the error in its
constructor, and from there the AsyncCompletedEventArgs object constructed in
SmtpClient.SendAsync always has its Error property equal to null.

My proposed solution, contained in the attached patch, simply rethrows the
exception caught in SmtpClient.SendAsync which enables the error to reach the
BackgroundWorker and be handled there.

-- 
Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list