What if TinyURL API doesn't work..?

2019-08-30 10:03发布

问题:

I have a vbscript function to create a tinyurl from a regular url.

FUNCTION GetShortURL(strUrl)
  Dim oXml,strTinyUrl,strReturnVal
  strTinyUrl = "http://tinyurl.com/api-create.php?url=" & strUrl
  set oXml = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
  oXml.Open "GET", strTinyUrl, false
  oXml.Send
  strReturnVal = oXml.responseText
  Set oXml = nothing
  GetShortURL = strReturnVal
END FUNCTION

I have come across the problem when the tinyurl api is down or inaccessible, making my script fail:

msxml3.dll error '80072efe' The connection with the server was terminated abnormally

Is there a safeguard I can add to this function to prevent the error and use the long url it has..?

Many thanks in advance,

neojakey

回答1:

If you want to just return strUrl if the call fails, you can use On Error Resume Next

FUNCTION GetShortURL(strUrl)
  on error resume next
  Dim oXml,strTinyUrl,strReturnVal
  strTinyUrl = "http://tinyurl.com/api-create.php?url=" & strUrl
  set oXml = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
  oXml.Open "GET", strTinyUrl, false
  oXml.Send
  strReturnVal = oXml.responseText
  Set oXml = nothing
  'Check if an error occurred.
  if err.number = 0 then
     GetShortURL = strReturnVal
  else
     GetShortURL = strUrl
  end if
END FUNCTION


回答2:

Obviously, you need some kind of error handling. In general, VBScript's error handling is no fun, but for your specs - get the right thing or the default in case of any/don't care what problem - you can use a nice and simple approach:

Reduce your original function to

  1. assignment of default value to function name (to prepare for the failures)
  2. On Error Resume Next (to disable VBScript's default error handling, i.e. crash)
  3. assignment of the return value of a helper function to function name (to prepare for success)

In code:

Function GetShortURL2(strUrl)
  GetShortURL2 = strUrl
 On Error Resume Next
  GetShortURL2 = [_getshorturl](GetShortURL2)
End Function

I use [] to be able to use an 'illegal' function name, because I want to emphasize that _getshorturl() should not be called directly. Any error in _getshorturl() will cause a skip of the assignment and a resume on/at the next line (leaving the function, returning the default, reset to default error handling).

The helper function contains the 'critical parts' of your original function:

Function [_getshorturl](strUrl)
  Dim oXml : Set oXml = CreateObject("Msxml2.ServerXMLHTTP.3.0")
  oXml.Open "GET", "http://tinyurl.com/api-create.php?url=" & strUrl, False
  oXml.Send
  [_getshorturl] = oXml.responseText
End Function

No matter which operation fails, the program flow will resume on/at the "End Function" line of GetShortURL2().

Added: Comments on the usual way to do it (cf. Daniel Cook's proposal)

If you switch off error handling (and "On Error Resume Next" is just that) you are on thin ice: all errors are hidden, not just the ones you recon with; your script will do actions in all the Next lines whether necessary preconditions are given or preparations done.

So you should either restrict the scope to one risky line:

Dim aErr
...
On Error Resume Next
   SomeRiskyAction
   aErr = Array(Err.Number, Err.Description, Err.Source)
On Error Goto 0
If aErr(0) Then
   deal with error
Else
   normal flow
End If

or check after each line in the OERN scope

On Error Resume Next
   SomeRiskyAction1
   If Err.Number Then
      deal with error
   Else
      SomeRiskyAction2
      If Err.Number Then
         deal with error
      Else
         ...
      End If
   End If

That's what I meant, when I said "no fun". Putting the risky code in a function will avoid this hassle.