how to check if a line of code actually succeeded? - vb.net

I'm making an email sending program and still I don't know how to check if the mail was really sent or not, because sometimes the program will have no error messages but the mail was not actually sent. Is there any other way on how to deal with this except for making use of try catch?
Here is my code:
Try
mail.From = New MailAddress(TextBox2.Text)
mail.To.Add(New MailAddress(TextBox1.Text))
mail.Subject = TextBox4.Text
mail.Body = TextBox4.Text
mail.IsBodyHtml = True
Dim client As SmtpClient = New SmtpClient("smtp.gmail.com", 587)
If TextBox2.Text.Contains("#gmail.com") Then
client.EnableSsl = True
client.Credentials = New System.Net.NetworkCredential(TextBox2.Text, TextBox3.Text)
Try
client.Send(mail)
Catch ex As Exception
MessageBox.Show("Sending email failed. Please Try again")
End Try
End If
Catch
MsgBox("Please input the correct value!")
End Try
ProgressBar1.Value = 100
clear()

I would typically use try/catch for this sort of thing.
Instead of catching a Generic Exception you can catch SmtpException and SmtpFailedRecipientsException's.
SmtpException is thrown when a connection could not be made or operation timed out. SmtpFailedRecipientsException is thrown if The message could not be delivered to one or more of the recipients.
Converted MSDN Code
Try
client.Send(message)
Catch ex As SmtpFailedRecipientsException
For i As Integer = 0 To ex.InnerExceptions.Length - 1
Dim status As SmtpStatusCode = ex.InnerExceptions(i).StatusCode
If status = SmtpStatusCode.MailboxBusy OrElse status = SmtpStatusCode.MailboxUnavailable Then
Console.WriteLine("Delivery failed - retrying in 5 seconds.")
System.Threading.Thread.Sleep(5000)
client.Send(message)
Else
Console.WriteLine("Failed to deliver message to {0}", ex.InnerExceptions(i).FailedRecipient)
End If
Next
Catch ex As Exception
Console.WriteLine("Exception caught in RetryIfBusy(): {0}", ex.ToString())
End Try

Another problem you may run into is that the mail is being sent but it is not getting there due to spam filtering. If it works to one email address it should work for all ignoring the TextBox2 check for gmail address.

You can use a bool method which always returns true or false of your sending status.
If you have no error then please check the emailId whether it exists or not.

Related

The underlying connection was closed thrown in 40th iteration of VB.Net application

This question appears multiple times on StackExchange but I just can't solve it. Most answers say that this arises due to SSL or TLS issues and to set the protocol to TLS10 or to use KeepAlive.
In my case, I am calling my own PHP endpoint and not using SSL. The server is hosted on GoDaddy.
I am retrieving records from the server. Due to the large size of the returned data, I placed the calls in a loop. The loop runs and fetches data for 40-50 iterations before throwing this error. It is not a timeout issue as the error is thrown within milliseconds.
I suspect a stream or connection is not closing and the VB.Net program is running out of resources or the server has too many open connections.
The code below is slightly abridged to remove sensitive info:
While True
' Create the request
uri = New Uri(My.Settings.ServerURL & My.Settings.GetEmployeeRecords)
request = DirectCast(WebRequest.Create(uri), HttpWebRequest)
' Add user credentials
creds = New CredentialCache
creds.Add(uri, "Basic", New NetworkCredential(My.Settings.UserId, My.Settings.Password))
With request
.Method = "POST"
.ContentType = "application/x-www-form-urlencoded"
.AutomaticDecompression = DecompressionMethods.GZip + DecompressionMethods.Deflate
.Credentials = creds
.KeepAlive = False
.ProtocolVersion = HttpVersion.Version10
.ConnectionGroupName = Guid.NewGuid().ToString()
.UserAgent = "VB.NET App"
.AllowAutoRedirect = False
End With
' Add parameters
strPostData = String.Format("offset={0}&limit={1}", iOffset, iLimit)
request.ContentLength = strPostData.Length
Try
Using sw As New StreamWriter(request.GetRequestStream)
sw.Write(strPostData)
sw.Close()
End Using
Catch ex As Exception
e.Result = "Error Setting Request Data"
Exit Sub
End Try
' Send the request to the server
Try
response = DirectCast(request.GetResponse, HttpWebResponse)
Catch ex As WebException
e.Result = "Error Sending Request" **<-- This is where it is thrown**
Exit Sub
End Try
' Open the response
Try
reader = New StreamReader(response.GetResponseStream)
Catch ex As Exception
e.Result = "Error Reading Request"
Exit Sub
End Try
' Read the full response
rawresp = reader.ReadToEnd()
reader.Close()
response.Close()
' We should never get a blank response
If rawresp = "" Or rawresp = "[]" Then
e.Result = "Blank Response"
Exit Sub
End If
' The response should be in JSON. Parse it
Try
jResults = Linq.JObject.Parse(rawresp)
Catch ex As Exception
e.Result = "Error parsing response"
Exit Sub
End Try
' Get the complete response into jResults
' The jResults would contain {statuscode, statusDescription, data[]} where the data element would be an array of employees
' Check for error returned in response JSON
If jResults("statusCode").ToString = "404" Then
Exit While
End If
If jResults("statusCode").ToString <> "0" Then
e.Result = "Error received from server"
Exit Sub
End If
' Get the array for the employee records
Try
jEmployees = Linq.JArray.Parse(jResults("data").ToString)
Catch ex As Exception
e.Result = "Response Does Not Contain Employee Array"
Exit Sub
End Try
' Everything is fine. Add the recordds to the local database
SaveEmployeesToLocalDB(jEmployees)
iCount = jEmployees.Count
iOffset += iCount
iTotalRecords += iCount
If iCount = 0 Then
Exit While
End If
If iTotalRecords Mod (20 * iLimit) = 0 Then
Application.DoEvents()
Threading.Thread.Sleep(3000)
End If
End While

Check if SMTP is running or failed to send email

I am using SMTP server to send emails.
I would like to get an error message when the SMTP server is down or when the email was not delivered.
With DeliveryNotificationOptions.OnFailure I get an email that the email has not been delivered.
I would like to get an error. Is this possible?
How I can check if SMTP is running?
Here is the code I use:
Dim serverName As String = ""
Dim mailSenderInstance As SmtpClient = Nothing
Dim AnEmailMessage As New MailMessage
Dim sendersEmail As String = ""
Try
serverName = GetServerName("EMAIL_SERVER")
mailSenderInstance = New SmtpClient(serverName, 25)
sendersEmail = GetSendersEmail(msUserName)
AnEmailMessage.From = New MailAddress(sendersEmail)
'MAIL DETAILS
AnEmailMessage.Subject = "New Email"
AnEmailMessage.Body = "The Message"
AnEmailMessage.To.Add(anEmailAddress)
' Delivery notifications
AnEmailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure
mailSenderInstance.UseDefaultCredentials = True 'False
mailSenderInstance.Send(AnEmailMessage)
Catch ex As System.Exception
MessageBox.Show(ex.ToString)
Finally
AnEmailMessage.Dispose()
mailSenderInstance.Dispose()
End Try
add another try catch block around your SMTP declaration
try
mailSenderInstance = New SmtpClient(serverName, 25)
catch ex as exception
msgbox( "Error creating SMTP connection: " & ex.message)
end try
regards
ok, you want to know the SMTP status. SMTP runs as a Service. I've written a function for you to know status of ANY service in the system. Add reference to "System.ServiceProcess" to your project.
''response: -1 = service missing, 0 = stopped or stopping, 1 = running
imports System.ServiceProcess ''add this at top
Private Function GetServiceStatus(ByVal svcName As String) As Integer
Dim retVal As Integer
Dim sc As New ServiceController(svcName)
Try
If sc.Status.Equals(ServiceControllerStatus.Stopped) Or sc.Status.Equals(ServiceControllerStatus.StopPending) Then
retVal = 0
Else
retVal = 1
End If
Catch ex As Exception
retVal = -1
End Try
Return retVal
End Function
use it like this:
'' use taskManager to figure correct service name
dim svStatus as integer = GetServiceStatus("SMTP")
if svStatus <> 1 then
msgbox("Service not running or absent")
else
''write your send mail code here
end if
hope this will help you

Object variable or With block variable not set?

I get this error when i run my program:
A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.VisualBasic.dll
Object variable or with block variable not set
Here is my code:
Dim rt As String = ""
Dim out As String
Dim wRequest As WebRequest
Dim wResponse As WebResponse
Dim SR As StreamReader
Dim time As Date
time = Now()
Try
wRequest = WebRequest.Create(Address)
wRequest.Timeout = 10000
wResponse = wRequest.GetResponse
SR = New StreamReader(wResponse.GetResponseStream)
rt = SR.ReadToEnd
SR.Close()
Catch wex As WebException
Dim status As WebExceptionStatus = wex.Status
If status = WebExceptionStatus.Timeout Then
MessageBox.Show("Could not establish a connection to the selected exchange server.", "Connection Timed Out", MessageBoxButtons.OK, MessageBoxIcon.Warning)
ElseIf status = WebExceptionStatus.ConnectFailure Then
MessageBox.Show("Could not establish a connection to the selected exchange server.", "Connection Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning)
ElseIf status = WebExceptionStatus.ProtocolError Then
MessageBox.Show("Could not establish a connection to the selected exchange server.", "Connection Protocol Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Try
The source of your error could be your Address variable.
Please try prefix with http:// in front.
Example:
Address = "http://www.google.com"
for more further information, please read MSDN WebRequest.Create Method (String)
The problem is most likely that wResponse.GetResponseStream is failing because wResponse is null. (which is probably because your Address variable isn't valid).
Try adding
Catch ex As Exception
MessageBox.Show("Some other error occurred: " + ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Warning)
End Try
after your WebException Catch block to see what the problem is.
Or just put a breakpoint on SR = New StreamReader(wResponse.GetResponseStream) and look at wResponse (your choice).
I am checking your code and it works fine.
Here's a demo although I made a little change on the declaration of time variable and putting a string on WebRequest.Create() like:
Dim time As Date = Now
and
WebRequest.Create("https://www.google.fm")
And as per my own search there is nothing much to be concerned about with this kind of error, see the link below.
A first chance exception

System.Net.Mail VB.NET 3.5 System.Net.Mail.SmtpException

I have searched the net thoroughly for a solution to this and have yet to find one.
I'm trying to establish a simple mail client to send text documents as raw text through SMTP. To do this I am using the System.Net.Mail library under VB.Net version 3.5
Whenever I try to send a message, I receive a System.Net.Mail.SmtpException.
I have tried using different mail providers, under different settings and have yet to solve this problem. This problem has been tested on 3 separate computers, all with different specifications.
The code is as follows:
Private Sub SendEmailMessage()
Try
If My.Computer.Network.IsAvailable Then
If DataValid() Then
'Data is valid, send the eMail.
Dim MailReceiver As String = txtReceiver.Text
'Create the eMail Message.
'Dim message As New MailMessage(from:=txtMailAddress.Text, to:=MailReceiver, subject:="(MTG) <CARD> " & ID, body:="<p>" & ConstructedFileString() & "<p>")
Dim message As New MailMessage
Dim MessageFrom As New MailAddress(txtMailAddress.Text)
Dim MessageTo As New MailAddress(MailReceiver)
With message
.From = MessageFrom
.To.Add(MailReceiver)
.Subject = "(MTG) CARD " & ID
.IsBodyHtml = True
.Body = "<p>" & ConstructedFileString() & "<p>"
End With
'Establish eMail Client
Dim emailClient As New SmtpClient()
Dim emailCredentials As New Net.NetworkCredential
With emailCredentials
.UserName = txtMailAddress.Text
.Password = txtPassword.Text
.Domain = "gmail.com"
End With
With emailClient
.Host = txtHostServer.Text
.Port = txtPort.Text
.Credentials = emailCredentials
.EnableSsl = chkSSL.Checked
.Timeout = 5000
End With
'Dim MailDomain As String = ""
'Dim PositionAt As Byte = 0
'PositionAt = txtMailAddress.Text.IndexOf("#")
'For i = PositionAt + 1 To Len(txtMailAddress.Text)
' MailDomain = MailDomain & txtMailAddress.Text.Chars(i)
'Next
'Debug.Print(MailDomain)
If My.Computer.Network.Ping(hostNameOrAddress:=emailClient.Host) Then
'Send the message.
emailClient.Send(message)
Else
'Could not ping, do not send.
ErrorOut("Could not reach the eMail Server.")
End If
Else
'Data is not valid, do not send the eMail.
End If
Else
ErrorOut("No network could be found. Check your network configurations.")
End If
Catch ex As Security.SecurityException
'Security exception
ErrorOut("A Security Exception was raised.")
Catch ex As Net.NetworkInformation.NetworkInformationException
'Network info exception
ErrorOut("Exception raised when retrieving network information.")
Catch ex As Net.NetworkInformation.PingException
'Ping exception
ErrorOut("Exception raised when pinging the network.")
Catch ex As Net.Mail.SmtpFailedRecipientException
'Recipient exception
ErrorOut("Mail Recipient Exception raised.")
Catch ex As Net.Mail.SmtpException
'Mail Server Exception
ErrorOut("Mail Server Exception raised")
Catch ex As Exception
'Generic Exception raised.
ErrorOut("General Exception raised", True)
End Try
End Sub
Any help on this matter is greatly appreciated, thanks.
Stack trace:
System.Net.Mail.SmtpException: The operation has timed out.
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at NetProj.EmailDialog.SendEmailMessage() in ...
I believe this is the famous SSL issue with System.Net.Mail
http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx
It was there in framework 3.5 not sure about 4.0 if they fixed it or not.

smtp.send failure sending email message from client machine

Mail.From = New Net.Mail.MailAddress(test#gmail.com)
Mail.To.Add("exc#gmail.com")
Mail.Subject = "Test"
Mail.Body = "Test"
Try
Dim mySmtp As New Net.Mail.SmtpClient("server")
mySmtp.Send(Mail)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try disabling the your Anti Virus as they can block SMTP calls.