0

I'm probably going about this the wrong way, as I have no experience with web requests, so please bear with me.

I'm trying to execute the following code:

webClient.DownloadStringAsync(New Uri("http://localhost:8115/"))

This works fine when the URI is available. However, if it is not available (ie. if the respective service is not running and is not exposing the relevant data), I get the following error message:

SocketException occurred: No connection could be made because the target machine actively refused it.

So, I tried to implement a try/catch block as follows:

If Not webClient.IsBusy Then
    Try
        webClient.DownloadStringAsync(New Uri("http://localhost:8115/"))
    Catch ex As Sockets.SocketException
        MsgBox("Error. Service is not running. No data can be extracted.")
    End Try
End If

That did not work. VB.Net still does not display the message box. So, I tried something else:

If Not webClient.IsBusy Then
    Dim req As System.Net.WebRequest
    req = System.Net.WebRequest.Create(New Uri("http://localhost:8115/"))
    Dim resp As System.Net.WebResponse
    Dim ready As Boolean = False

    Try
        resp = req.GetResponse
        resp.Close()
        ready = True
    Catch ex As Sockets.SocketException
        MsgBox("Error. Service is not running. No data can be extracted.")
    End Try

    If ready Then
        webClient.DownloadStringAsync(New Uri("http://localhost:8115/"))
        ready = False
    End If
End If

It also doesn't work. I must be approaching this problem incorrectly. Can someone show me what the correct way of doing this is? Is there a way of first checking if the data exists, before running the DownloadStringAsync function?

Thanks!

Edit: To add context to the discussion under Visual Vincent's answer, here is what my code looks like. Just a single form.

Imports System.Net

Public Class Form1
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim webClient As New System.Net.WebClient
        Try
            WebClient.DownloadStringAsync(New Uri("http://localhost:8115"))
        Catch ex As System.Net.Sockets.SocketException
            MessageBox.Show("Error")
        Catch ex As System.Net.WebException
            MessageBox.Show("Error. Service is not running. No data can be extracted.")
        Catch ex As Exception
            MessageBox.Show("An error occurred:" & Environment.NewLine & ex.Message)
        End Try
    End Sub
End Class
Aommaster
  • 115
  • 15

1 Answers1

2

The WebClient.DownloadStringAsync() method doesn't throw a SocketException, but a WebException (perhaps with its inner-exception set to a SocketException).

From the documentation:

Exceptions

WebException

The URI formed by combining BaseAddress and address is invalid.

-or-

An error occurred while downloading the resource.

A SocketException is most of the time only thrown by raw sockets. Then the members of the System.Net namespace usually wrap these in a WebException.

So to fix your code:

Try
    webClient.DownloadStringAsync(New Uri("http://localhost:8115/"))
Catch ex As System.Net.WebException
    MessageBox.Show("Error. Service is not running. No data can be extracted.")
End Try

NOTE: I switched to MessageBox.Show() instead because MsgBox() is outdated, and only exists for backwards compatibility with VB6.

However, the best practice is to add another Catch statement that catches all other exceptions as well, so that you don't leave your application open to crashes.

You also ought to log the error message from the WebException, since it may be thrown for other reasons than just the endpoint not being available.

Try
    webClient.DownloadStringAsync(New Uri("http://localhost:8115/"))
Catch ex As System.Net.WebException
    MessageBox.Show("Error. Service is not running. No data can be extracted.")
Catch ex As Exception
    MessageBox.Show("An error occurred:" & Environment.NewLine & ex.Message)
End Try
Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
  • Thanks for your reply! I tried out your code, but unfortunately, it doesn't appear to fix the problem. I still get the same issue (message box not appearing). Is there something I have to change in my compiler's configuration? – Aommaster Feb 17 '18 at 16:00
  • @Aommaster : Even with the general `Catch ex As Exception` statement? Try resetting the exception settings in VS: https://blogs.msdn.microsoft.com/devops/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015/ – Visual Vincent Feb 17 '18 at 16:06
  • Hi! Yes even with the general Catch statement. I did a reset of all the exception settings from that dialog box. The exception no longer gets displayed (but again, it also doesn't display the message box). I do get this in the compiler output though: `A first chance exception of type 'System.Net.WebException' occurred in System.dll` – Aommaster Feb 17 '18 at 16:12
  • @Aommaster : That is always logged when an exception is thrown (handled or not), so that's normal. Though why the message box doesn't work is a mystery. What happens if you run this _**outside**_ Visual Studio? And what if you switch back to the (outdated :/) `MsgBox()`? – Visual Vincent Feb 17 '18 at 16:16
  • No luck on both fronts unfortunately. I tried running the fully-compiled executable and it doesn't display the message box. Even the outdated msgbox() function doesn't fix the issue. I'm wondering if there's some really simple, but obvious configuration change I might have overlooked. – Aommaster Feb 17 '18 at 16:29
  • @Aommaster : I doubt that. A simple setting can't disable a compiler-independent code feature. There is something else to it. Odd... – Visual Vincent Feb 17 '18 at 16:40
  • If a `Catch exW As WebException` block is set, an "Unable to connect to the remote server" exception is caught with `InternalStatus = ServicePointFatal` and `Status = ConnectFailure`. If it's not caught, it means that there's no catch block with a specific target for WebException. The exception the OP reports is the InnerException of an unhandled exception. – Jimi Feb 17 '18 at 17:27
  • @Jimi : I know that it is an inner-exception (as mentioned in the top of my answer), but it is wrapped in a `WebException`. The `WebException` _**is**_ thrown (as mentioned by the OP in [this comment](https://stackoverflow.com/questions/48842373/catching-a-socketexception/48842954?noredirect=1#comment84690642_48842954)), yet the message box never shows. This is caused by something else. – Visual Vincent Feb 17 '18 at 18:19
  • @Jimi : You also don't need a specific `Catch ex As WebException` in order to catch a `WebException`. The general `Catch ex As Exception` will catch _**all**_ exceptions that occur in the `Try` block, but even with that the OP can't get the message box to show. – Visual Vincent Feb 17 '18 at 18:25
  • @Aommaster : Try your code in a new project, and if it still behaves the same also try targeting a different version of .NET Framework. If only zero or one of these two suggestions work, try repairing your .NET installation. If both work, I honeslty don't know what to tell you... Check if you're changing any unusual settings in your code. You could also try asking over at [MSDN Forum](https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=vbgeneral) for additional feedback (provide information about the tests you've ran as well). – Visual Vincent Feb 17 '18 at 18:30
  • Yes, of course. But WebException will give you back some informations you won't otherwise get. I was telling you this, because it seems clear to me that your OP is not doing what he's telling. And I have tested it (of course). A WebException, in that situation, will raise and anything in the Try/Catch block will be executed. The only reason not to show that message, is because the exception is never caught. – Jimi Feb 17 '18 at 18:58
  • @Jimi : I don't really understand your point? And what do you mean by _"it seems clear to me that your OP is not doing what he's telling"_? – Visual Vincent Feb 17 '18 at 20:04
  • @Jimi : _"The only reason not to show that message, is because the exception is never caught."_ - Well it isn't unhandled either, seeing as the app didn't crash when he ran it outside Visual Studio. And the exception is thrown as indicated by the output from the Immediate Window that he shared in his comment. Something is either preventing the `Try/Catch` from detecting it, or the message box from being shown. This is really odd. – Visual Vincent Feb 17 '18 at 20:08
  • 1
    I'm saying that there's no way that the code he's using is the code he's saying he's using. Otherwise, the MessageBox would appear. Since the code in his question is simply wrong, he should show what he's actually doing now, after your suggestion (which is correct). I think that would clear things up (I'll stop messing with your answer now :). – Jimi Feb 17 '18 at 20:20
  • Hi! Thanks, both Visual Vincent and Jimi for trying to help. Unfortunately, repairing Visual Studio also did not fix the issue. I'm almost certain it must be a configuration-related issue on my end, however, I'm nowhere near experienced in VS to know what it could be. I actually created a new project file, declared the `webClient` variable, then put the try/catch block at the end of Visual Vincent's answer. It still doesn't display the error message (debug output shows the exceptions). I ran the executable from the release folder as well, and it doesn't crash or display any error messages. – Aommaster Feb 17 '18 at 20:34
  • To just add some emphasis on what code I'm running, I've edited my original question and put the code I currently have in that new project. – Aommaster Feb 17 '18 at 20:44
  • @Aommaster : Try repairing .NET Framework as well. Also in your new project try targeting an older .NET version like 3.5 and see if the problem still persists. – Visual Vincent Feb 17 '18 at 23:31
  • @Jimi : Ah, okay. The way I previously interpreted your comments I thought you were basically saying _"you're wrong"_, but I see what you meant now :). What confused me the most was when you said "your OP" - with which I thought you meant "your Original _**Post**_" rather than _Poster_. ;) – Visual Vincent Feb 17 '18 at 23:46
  • Tried that, but it didn't work. I did a little bit more research and found a couple of threads [here](https://stackoverflow.com/questions/32810051/cannot-catch-socketexception) and [here](https://stackoverflow.com/questions/22569243/handle-a-exception-that-happens-in-a-asynchronous-method-in-c-sharp). While those are in C#, I believe the framework shouldn't behave differently. Is it possible that Async methods cannot be caught by a Try/Catch? Because I am using an async method in this. – Aommaster Feb 18 '18 at 08:44
  • @Aommaster : While the name suggests that it is asynchronous, the method itself isn't actually marked as `Async` (as seen in [**the docs**](https://msdn.microsoft.com/en-us/library/ms144202(v=vs.110).aspx) it just says `Public Sub`). The `DownloadStringAsync()` method has existed since .NET 2.0 and hasn't really changed since. All it does is starting an asynchronous operation, which in this case is not the same as calling an actual `Async` method. You should be able to catch the exception, otherwise your app would crash even with `Try/Catch`. – Visual Vincent Feb 18 '18 at 09:06
  • My bad, poor phrasing. (btw, I'ld really get rid of that `Catch ex As System.Net.Sockets.SocketException` on top of the Catch block :) – Jimi Feb 18 '18 at 15:36
  • @Jimi : Tell that to the OP, I don't have it. ;) – Visual Vincent Feb 18 '18 at 16:31