Issue with XmlDocument - vb.net

I've got an intermittent issue with a sub that goes off to read a twitter rss feed.
95% of the time, it behaves fine and without problems. The remaining 5% it gives me a 400 Bad Request error (even though the rss feed on Twitter is just fine, which suggests that the problem is at my end, not Twitter.)
Code:
Sub RetrieveStories()
'Create a new xmldocument and load the xml into it
Dim rssDoc As New XmlDocument
rssDoc.Load("http://twitter.com/statuses/user_timeline/athersgeo.rss")
'Select each item and put it into our array
Dim nodes As XmlNodeList = rssDoc.SelectNodes("rss/channel/item")
Dim i as integer = 1
divMRSS.InnerHtml = ""
Dim TweetText as string
Dim TweetURL as string
Dim UNameLen as integer = 15
For Each node As XmlNode In nodes
'Using xpath we can acess all the data we need in each node
TweetURL = node.SelectSingleNode("link").InnerText
TweetText = Mid(node.SelectSingleNode("title").InnerText,UNameLen)
TweetText = Linkify(TweetText)
TweetText = Atify(TweetText)
TweetText = Hashify(TweetText)
TweetText = "#athersgeo: " & TweetText
divMRSS.InnerHtml += "" & TweetText & "<BR>" & RelativeTime(node.SelectSingleNode("pubDate").InnerText) & "<BR><HR>"
i = i + 1
If i = 5 then
Exit For
End if
Next
End Sub
Is there something that I'm not closing/disposing of that's sucking up connections? Or have I just coded something blindingly stupid? (Which wouldn't be the first time!)

400 Bad Request is associated with HTTP. From your code it seems the only HTTP request is to load the xmlDocument rssDoc.Load("http://twitter.com/statuses/user_timeline/athersgeo.rss").
But you mention that - the rss feed on Twitter is just fine - how could you ensure that?
As suggested in this blog you could use Fiddler to explore your request going out to twitter - http://blogs.msdn.com/b/hakane/archive/2009/06/30/investigating-http-400-bad-request-errors-in-web-access.aspx

Related

HttpWebRequest Timeout updating status Code in BigCommerce

I have read a lot, if not all the posts, on timeouts for web requests and the solutions provided have not worked. I am getting orders from Big Commerce and then updating the Big Commerce status code. I can update 2 orders and then I timeout on the third, every single time regardless of day of week or time of day.
App.Config file has:
```
<system.web>
<httpRuntime executionTimeout="180" />
</system.web>
```
Code:
```
Try
Dim strJSON As String = "{""status_id"": 9}"
Dim postBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(strJSON)
For i As Integer = 0 To dto.Rows.Count - 1
strWebOrder = dto.Rows(i).Item("WebOrder")
Dim strHttp As String = "https://api.bigcommerce.com/stores/storeid/v2/orders/" & strWebOrder
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(strHttp), HttpWebRequest)
request.Accept = "application/json"
request.ContentType = "application/json"
request.Headers("X-Auth-Token") = strAuthToken
request.Timeout = 10000
request.AllowWriteStreamBuffering = False
request.SendChunked = True
request.Method = "PUT"
Dim postStream As Stream = request.GetRequestStream()
postStream.Write(postBytes, 0, postBytes.Length)
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
If response.StatusCode = 200 Then
strErrorRef = "Web " & strWebOrder
strErrorReason = "Order Status Changed to Exported"
strPutMessage = ""
WriteError()
Else
strErrorRef = "Web " & strWebOrder
strErrorReason = "Unable to change Web Order Status to Exported"
strPutMessage = ""
WriteError()
End If
Next
Catch ex As Exception
strErrorRef = "Web " & strWebOrder
strErrorReason = "Unable to change Web Order Status to Exported"
strPutMessage = (ex.ToString)
WriteError()
End Try
```
Have you tried to increase the seconds in your executionTimeout property? If you increase it to 300, this will give your application 5 minutes to execute the command before it’s shut down, rather than the 3 minutes you’re currently using.
I’m not sure what all you’ve tried or read into, but it sounds like the code you have is taking at least 2-3 minutes to get through 2 orders, so that’s why the result you see is the same regardless of the time of day it’s being executed.
Have you tried to refactor the code to break it up a bit, for example:
grab all orders with status_id 9 in one function OR
store these order_ids in an array in another function elsewhere, then in a new function loop through the stored array to update the status_id?
Also, are you using webhooks at all?

Searching text file and showing part of the text in a text box

I am working on a VB.net application where I have a very large text file. It is basically a large database of error codes with descriptions of how to clear the code after it. What I would like to do, is on the click of a button, search the text file for the specific code and display all text for just that error code into a text box. I have tried many different ways, but am unable to get it to work properly. I went through the entire text file and added a "|" to the beginning of each fault code so that I could specify where the code starts at.
Here is an example of a couple fault codes:
|ACAL-000 Fail to run DETECT Motn Cause: The AccuCal2 Motion failed to
nm. The AccuCal2 motion cannot be started. Remedy: Clear all the
errors before executing AccuCal2. |ACAL-001 Robot is not ready.
Cause: The robot is not ready. The system cannot issue motion
because it is in an error state. Remedy: Clear all faults, then retry
the operation.
If I search for "ACAL-000", I want it to show everything from the | before ACAL-000 to the bar before ACAL-001.
I would post the code that I have written, but I have tried so many different versions that I don't really know which one to post.
Any help you can provide would be greatly appreciated.
EDIT
Here is my current code after some editing and implementation of what has been recommended. Please see the comments below for more information on how I got to this point. A quick note, I am currently just using "|ACAL-000" for a test search. When this is complete, I have some other (already working) code that will put together a code from a couple of drop down lists.
Function ReadEmbeddedTextFileResource(embeddedResourceName As String) As String
Using stream As Stream = Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedResourceName)
If stream Is Nothing Then
Throw New FileNotFoundException("The resource '" & embeddedResourceName & "' was not found.")
End If
Using reader As StreamReader = New StreamReader(stream, True)
Return reader.ReadToEnd()
End Using
End Using
End Function
Function FindTextBetweenBars(bodyOfTextToSearch As String, textToLookFor As String) As String
Dim i As Integer = bodyOfTextToSearch.IndexOf(textToLookFor)
If i < 0 Then Return Nothing
Dim j As Integer = bodyOfTextToSearch.LastIndexOf("|", i)
If j < 0 Then j = 0
Dim k As Integer = bodyOfTextToSearch.IndexOf("|", i + Len(textToLookFor))
If k < 0 Then k = Len(bodyOfTextToSearch)
Return bodyOfTextToSearch.Substring(j + 1, k - j - 1)
End Function
Private Sub btnShowTroubleshooting_Click(sender As Object, e As EventArgs) Handles btnShowTroubleshooting.Click
Dim allErrorText As String = ReadEmbeddedTextFileResource(My.Resources.FanucCodes)
Dim errorMessage As String = FindTextBetweenBars(allErrorText, "|ACAL-000")
If errorMessage Is Nothing Then errorMessage = "Error code Not found!"
RichTextBoxFanucFaults.Text = errorMessage
End Sub
Here is a function that should do what you want:
Function FindTextBetweenBars(bodyOfTextToSearch As String, textToLookFor As String) As String
Dim i As Integer = bodyOfTextToSearch.IndexOf(textToLookFor)
If i < 0 Then Return Nothing
Dim j As Integer = bodyOfTextToSearch.LastIndexOf("|", i)
Dim k As Integer = bodyOfTextToSearch.IndexOf("|", i + Len(textToLookFor))
If k < 0 Then k = Len(bodyOfTextToSearch)
Return bodyOfTextToSearch.Substring(j + 1, k - j - 1)
End Function
In your button click event handler you can call the function like this:
Dim errorMessage as String = FindTextBetweenBars(My.Resources.FanucCodes, txtErrorCodeToLookFor.Text)
If errorMessage Is Nothing Then errorMessage = "Error code not found!"
txtErrorMessage.Text = errorMessage
where txtErrorMessage is the output textbox to display the error message result,
My.Resources.FanucCodes is your large string resource containing all the error descriptions (with | separators), and txtErrorCodeToLookFor is a textbox that accepts the error code input from the user.

FileInfo returning wrong value?

Okay, so I'm working in VB.NET, manually writing error logs to log files (yes, I know, I didn't make the call). Now, if the files are over an arbitrary size, when the function goes to write out the new error data, it should start a new file with a new file name.
Here's the function:
Dim listener As New Logging.FileLogTraceListener
listener.CustomLocation = System.Configuration.ConfigurationManager.AppSettings("LogDir")
Dim loc As String = DateTime.UtcNow.Year.ToString + DateTime.UtcNow.Month.ToString + DateTime.UtcNow.Day.ToString + DateTime.UtcNow.Hour.ToString + DateTime.UtcNow.Minute.ToString
listener.BaseFileName = loc
Dim logFolder As String
Dim source As String
logFolder = ConfigurationManager.AppSettings("LogDir")
If ex.Data.Item("Source") Is Nothing Then
source = ex.Source
Else
source = ex.Data.Item("Source").ToString
End If
Dim errorFileInfo As New FileInfo(listener.FullLogFileName)
Dim errorLengthInBytes As Long = errorFileInfo.Length
If (errorLengthInBytes > CType(System.Configuration.ConfigurationManager.AppSettings("maxFileSizeInBytes"), Long)) Then
listener.BaseFileName = listener.BaseFileName + "1"
End If
Dim msg As New System.Text.StringBuilder
If String.IsNullOrEmpty(logFolder) Then logFolder = ConfigurationManager.AppSettings("LogDir")
msg.Append(vbCrLf & "Exception" & vbCrLf)
msg.Append(vbTab & String.Concat("App: AppMonitor | Time: ", Date.Now.ToString) & vbCrLf)
msg.Append(vbTab & String.Concat("Source: ", source, " | Message: ", ex.Message) & vbCrLf)
msg.Append(vbTab & "Stack: " & ex.StackTrace & vbCrLf)
listener.Write(msg.ToString())
listener.Flush()
listener.Close()
I have this executing in a loop for testing purposes, so I can see what happens when it gets (say) 10000 errors in all at once. Again, I know there are better ways to handle this systemically, but this was the code I was told to implement.
How can I reliably get the size of the log file before writing to it, as I try to do above?
Well, as with many things, the answer to this turned out to be "did you read your own code closely" with a side order of "eat something, you need to fix your blood sugar."
On review, I saw that I was always checking BaseFileName and, if it was over the arbitrary limit, appending a character and writing to that file. What I didn't do was check to see if that file or, indeed, other more recent files existed. I've solved the issue be grabbing a directory list of all the files matching the "BaseFileName*" argument in Directory.GetFiles and selecting the most recently accessed one. That ensures that the logger will always select the more current file to write to or -if necessary- use as the base-name for another appended character.
Here's that code:
Dim directoryFiles() As String = Directory.GetFiles(listener.Location.ToString(), listener.BaseFileName + "*")
Dim targetFile As String = directoryFiles(0)
For j As Integer = 1 To directoryFiles.Count - 1 Step 1
Dim targetFileInfo As New FileInfo(targetFile)
Dim compareInfo As New FileInfo(directoryFiles(j))
If (targetFileInfo.LastAccessTimeUtc < compareInfo.LastAccessTimeUtc) Then
targetFile = directoryFiles(j)
End If
Next
Dim errorFileInfo As New FileInfo(listener.Location.ToString() + targetFile)
Dim errorLengthInBytes As Long = errorFileInfo.Length

Get page number of IndirectObject in ABCPdf

I have a script which processes indirect objects from the object soup (it processes the images of the PDF).
So, I have the IndirectObject, and I need the page number on which it is:
var indiObj = sourceDoc.ObjectSoup[objectToProcess];
I have tried to use sourceDoc.GetInfo(indiObj.ID, "whatever"); but I have no idea which property to use as type, because I couldn't find any documentation of the list of possible properties.
I asked about the version because I'm working with version 7 :(
It's an interesting question (IMHO). I thought first that this could be useful:
oDoc.ObjectSoup.Catalog.Pages.GetPageArray
But, altough you get the pages, you can't get the object soup for each page (at least in version 7) .....
So, maybe, you can try something like this, as PDF code in 'objects soup' it's order from top to botton:
Dim oDoc As New WebSupergoo.ABCpdf7.Doc
Using oDoc
oDoc.Read(path_to_your_PDF)
Dim iPage As Integer = 0
Dim sType As String
For iAux As Integer = 0 To oDoc.ObjectSoup.Count - 1
sType = oDoc.ObjectSoup(iAux).GetType.ToString()
Select Case sType
Case "WebSupergoo.ABCpdf7.Objects.Page"
iPage += 1
Debug.Print(vbNewLine & "Page " & iPage.ToString & " detected")
Case "WebSupergoo.ABCpdf7.Objects.PixMap"
Dim oPDFImg As WebSupergoo.ABCpdf7.Objects.PixMap
oPDFImg = CType(oDoc.ObjectSoup(iAux), WebSupergoo.ABCpdf7.Objects.PixMap)
Debug.Print(vbNewLine & "Image on page " & iPage.ToString & " -> ID " & oPDFImg.ID.ToString)
End Select
Next
End Using
You can use a "typeof" instead of that Select Case (change 'ABCpdf7' to 'ABCpdf9', anyway). Hope it helps.

Index was outside the bounds of the array [VB.NET]

Hi i am new to VB and in the process of learning. This error occur sometimes and doesn't occur sometimes which i find it weird.
I receive the error Index was outside the bounds of the array, that points to Button30.Text = Split(newestversion, vbCrLf)(**1**)
My motive is to read line by line from a online hosted text file.
For example,
label1.text = line 1 of the text file
label2.text = line 2 of the text file
This is very much what i want.
Here is my current code (EDITED):
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("direct link to my online txt file")
Dim response As System.Net.HttpWebResponse = request.GetResponse
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(response.GetResponseStream)
Dim stringReader As String
stringReader = sr.ReadLine()
Button10.Text = stringReader
Dim newestversion As String = sr.ReadToEnd
Dim currentversion As String = Application.ProductVersion
Dim part() As String = Split(newestversion, vbCrLf)
If part.Length < 10 Then
' not enough items in the array. You could also throw and exception or do some other stuff here
Label10.Text = "beta"
Exit Sub
End If
'updates new episode numbers on buttons
Button20.Text = part(0)
Button30.Text = part(1)
Button40.Text = part(2)
Button50.Text = part(3)
Button60.Text = part(4)
Button70.Text = part(5)
Button80.Text = part(6)
Button90.Text = part(7)
Button100.Text = part(8)
Button110.Text = part(9)
End If
Thank You!!
You split your String for line breaks. This gives you an array, having one entry for each line in the String. However, you do not check if this array holds the amount of items you expect. You could do:
Dim newestversion As String = sr.ReadToEnd
Dim currentversion As String = Application.ProductVersion
Dim part() As String = Split(newestversion, vbCrLf)
If part.Length < 10 Then
' not enough items in the array. You could also throw and exception or do some other stuff here
MsgBox(String.Format("Array only has {0} items", part.Length))
Exit Sub
End If
'updates new episode numbers on buttons
Button20.Text = part(0)
Button30.Text = part(1)
Button40.Text = part(2)
...
Edit for the updated question
If you do have a problem like this, just approach it systematically and get as much information as you can. First you have to check if you really get the data you want from the remote source. To do that, add some logging (e.g. a MsgBox(newestversion) or a real log file). Check if the data you get is what you expect. If not, there's already a problem with your request/response code, which is a completely different problem than what I provided a solution for. If newestversion is OK, check if the splitting works by printing out the part() array. Maybe the server uses a different operating system or just uses vbCr as newline and not vbCrlf. If the splitting also works, you are done.