Why in Classic ASP on Windows 10 a call to comp+ dll method generates error number -2147164123 with no description? - asp-classic

I hope I am placing my question in right place. I could not find closer tags.
I am setting up a new 64 bit system to have everything from my old 32 bit system on it.
I used vb6 to create an activeX dll test project to make a testProj.dll, package it and install it by running the setup.exe of the package as administrator.
My test project is called testProj having a class called testClass which has a simple sub called testSub as follows:
Public Sub testSub()
Response.Write “--------- testSub is called ----------“
End Sub
The testSub simply prints a message to confirm that the sub was called.
I successfully install / register the testProj.dll and on an asp page I successfully call the Server.CreateObject(“testProj.testClass”) to instantiate the testProj for calling its testSub().
On Error Resume Next
Dim testObj
Set testObj = Server.CreateObject(“testProj.testClass”)
if err.number <> 0 then
Response.write "1----------err.number = " & err.number & "--------- err.description = " & err.description
err.clear
end if
Call testObj.testSub()
if err.number <> 0 then
Response.write "2----------err.number = " & err.number & "--------- err.description = " & err.description
err.clear
end if
Set testObj = nothing
But the code generates error with no description:
2----------err.number = -2147164123 ---------err. description =
Also if I comment out the 'Call testObj.testSub()' I do not get any error. Meaning that the source of the error is the call to testSub().
I run everything as administrator so I do not expect any permission issue.
Could an expert tell me what the problem might be?
Thank you

It looks like you are assuming that you have access to the Classic ASP context from inside the COM DLL which will not be the case. The code is failing inside the COM DLL because it doesn't know what Response is which will trigger an Object Required error inside the DLL bubbling up to the Classic ASP page.
The simplest solution is to change what the method is sending back. As you can't call the Response.Write() method directly the next best thing is to return a string instead then use Response.Write() from the ASP page to display it.
Modify the COM DLL method to return a String;
Public Function testSub() As String
testSub = "--------- testSub is called ----------"
End Function
Then in the ASP page;
Call Response.Write(testObj.testSub())

Related

Error in Classic ASP page while reading rss feed

We have an old application developed in classic ASP and today it is generating an error while consuming RSS feed. After through investigating(tried to wrote code in .NET to get detailed error) found its special character, in generated output which is causing trouble. When you run RSS feed in browser and run generated XML from local server, it works fine.
Error: System error: -2147012866.
Line: 0
Text:
I have no idea how to fix it.
<%
Dim objXML
Dim objItemList
Dim objItem
Dim I
Set objXML = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
objXML.async = False
I = 0
objXML.setProperty "ServerHTTPSRequest", True
'objXML.Load(Server.MapPath("abcd.xml"))
objXML.Load("http://search.jobs.wa.gov.au/wagov.rss?agencyID=925")
If objXML.parseError.errorCode <> 0 Then
Response.Write "<pre>" & vbCrLf
Response.Write "<strong>Error:</strong> " & objXML.parseError.reason
Response.Write "<strong>Line:</strong> " & objXML.parseError.line & vbCrLf
Response.Write "<strong>Text:</strong> " & Server.HTMLEncode(objXML.parseError.srcText) & vbCrLf
Response.Write "</pre>" & vbCrLf
End If
%>
Zam,
Even if you correct it from ServerHTTPSRequest to ServerHTTPRequest in SetProperty, still nothing works.
As mentioned in question, it also worked fine when you use saved the XML file(generated from RSS FEED)
Also, if you look into below post, it states that it's all because of encoding="iso-8859-1" which is also the case for above issue.
http://stackoverflow.com/questions/4332828/vbscript-tries-to-read-rss-feeds-have-issue-of-system-does-not-support-the-speci
but solution provided there causes another error that The connection with the server was terminated abnormally
I believe error in objXML.SetProperty "ServerHTTPSRequest", True
Because
Error description: Property name is invalid.

Publishing page from workflow

Whenever page is created or modified we want it to be published to Staging target.
For this we have Manual Activity "Create or Edit Page", then we have automatic activity "Publish to Staging" in this we have written following code, but page is not getting published when it is created or modified. Also no error is shown how to debug where things are going wrong.
' Script for Automatic Activity Content Manager Workflow
Set oTDSE = CreateObject("TDS.TDSE")
Call oTDSE.Initialize
Set ObjCurrentItem = CurrentWorkItem.GetItem(3)
sDestinationServer = "tcm:0-2-65538"
Set oPage = oTDSE.GetObject(ObjCurrentItem.ID, 3)
Call oPage.Publish(sDestinationServer, True, True, True)
FinishActivity "Publish to Staging for Review"
set oPage = Nothing
set ObjCurrentItem = Nothing
set oTDSE = Nothing
Since you mentioned this is your first workflow implementation, here are some other basics to try/look for. Since this is a Page Workflow, I'm assuming that the Structure Group that you are creating/editing the page in has already been associated to a Workflow Process Definition in that SG's workflow tab.
Create a new page (or edit a page) in the SG with the Workflow process definition set.
Verify that the Page is locked and in Workflow. From the Shortcuts section, goto "My Tasks". You should see your page there. If not, then the SG is probably missing the Process Definition.
Right click the page from "My Tasks" and click "Finish Activity". This should finish your Manual Step and send it to your Automatic Activity. That Activity should then execute the script, which will publish the page and then finish the automatic activity, sending the workflow process to your next step.
Verify that the Page has been published (check publishing queue).
If the page has not been published, go to the page and check its status. If an error happens during an Automatic Activity, the workflow item will be "suspended" and stuck on that activity. If you see this, you can get details of the error from the Event Log under Source "Workflow Script".
If following the above, and the workflow item is moving along the workflow process correctly (getting past your automatic activity without error and to your next activity) and you are still not seeing it being published, then verify what Nuno suggested.
Also note that you don't have to open the page using the TDSE object as you already have it opened via the CurrentWorkItem.GetItem() method... your script can be shortened:
Dim ObjCurrentItem
Set ObjCurrentItem = CurrentWorkItem.GetItem()
Call ObjCurrentItem.Publish("tcm:0-2-65538", True, True, True)
FinishActivity "Publish to Staging for Review"
Set ObjCurrentItem = Nothing
As you can see this is a very old code but works to publish objects via Workflow. "This code also publishes the pages/where this items is referenced."
Apart from looking at various logs, would suggest set the clean=false and check till what point the packages are created. This will give you idea how far it has reached. Ofcourse put bit of debug messages to see if all executes well.
Sub WFPublishPages( ByRef oComponent, ByRef targets, ByRef activateBlueprinting, ByRef activateWorkflow, ByRef rollbackOnFailure, ByRef publishTime, ByRef unpublishTime, ByRef deployTime, ByRef resolveComponentLinks, ByRef priority, ByRef ignoreRenderFailures, ByRef maximumRenderFailures )
' If IsNull(publishTime) Then
' publishTime = 0
' End If
' If IsNull(unpublishTime) Then
' unpublishTime = 0
' End If
' If IsNull(deployTime) Then
' deployTime = 0
' End If
' If IsNull(resolveComponentLinks) Then
' resolveComponentLinks = True
' End If
' If IsNull(priority) Then
' priority = PublishPriorityNormal
' End If
' If IsNull(ignoreRenderFailures) Then
' ignoreRenderFailures = false
' End If
' Is IsNull(maximumRenderFailures) Then
' maximumRenderFailures = 0
' End If
Dim Debugstring
Debugstring = ""
Dim oLRF
Set oLRF = TDSE.CreateListRowFilter()
Call oLRF.SetCondition("ItemType", ItemTypePage)
Call oLRF.SetCondition("OnlyLatestItems", True)
Dim oXML
Set oXML = CreateObject("MSXML2.DOMDocument.6.0")
Call oXML.setProperty("SelectionNamespaces", "xmlns:tcm=""http://www.tridion.com/ContentManager/5.0"" xmlns:xlink=""http://www.w3.org/1999/xlink""")
Call oXML.loadXML(oComponent.Info.GetListUsingItems(XMLListID, oLRF))
Dim oNode
Dim oPage
Dim strPageID
Debugstring = Debugstring & " DUBUG: ComponentID " & oComponent.ID & vbCrLf
For Each oNode In oXML.selectNodes("/tcm:ListUsingItems/tcm:Item")
strPageID = oNode.selectSingleNode("#ID").text
Debugstring = Debugstring & " DUBUG: PageID " & strPageID & vbCrLf
Set oPage = TDSE.GetObject(strPageID, OpenModeView )
Debugstring = Debugstring & " DUBUG: oPage.Title "
Debugstring = Debugstring & oPage.Title
Debugstring = Debugstring & vbCrLf
Call oPage.Publish(targets , activateBlueprinting, activateWorkflow, rollbackOnFailure, publishTime, unpublishTime, deployTime, resolveComponentLinks, priority,ignoreRenderFailures,maximumRenderFailures )
Call WriteLog("Publish Page: " & oPage.Title & " for component " & oComponent.Title & " - renderTime is " & publishTime & " - deployTime is " & deployTime)
Set oPage = Nothing
Set oNode = Nothing
Next
Set oXML = Nothing
Set oLRF = Nothing
Thanks
Vin
Here's a few things you can test:
Run the publisher in debug mode (stop the service, open a command prompt, run c:\Program Files (x86)\Tridion\bin\TcmPublisher /debug) and check for errors
Try publishing the page from the "My Tasks" view
Check if your page's current approval status is higher or equal than the Publication Target's "Minimum approval Status"

Testing if object Is Nothing results in 'Object required' error

I am supporting some classic ASP pages, one of which uses and re-uses an object conn and disposes of it either when the .asp page finishes processing or right before the page redirects to another page.
<%
dim conn
...
set conn = server.CreateObject("adodb.connection")
...
sub cleanUp()
conn.Close
set conn = nothing
end sub
...
sub pageRedirect(url)
call cleanUp()
response.Redirect url : response.End
end sub
...
' very end of file
call cleanUp()%>
I've found that if there is a redirect, I get a server error right at the line conn.Close, Microsoft VBScript runtime error '800a01a8' Object required. I figure there's no reason why that line would execute more than once but to be safe I rewrote the function
sub cleanUp()
if(not (conn Is Nothing)) then
conn.Close
set conn = Nothing
end if
end sub
But I still get that exact error, now at the line if(not (conn Is Nothing))!! I thought the purpose of Is Nothing was to do a test before using the variable name conn precisely to prevent that 'object required' error, but the test is throwing the same error.
What other test can I use to make sure conn isn't referenced if it'd already been set to Nothing?
is nothing is used to test for an object reference, if the variable does not contain such then the test is invalid & raises an error, so conn can only be tested after its been set to something.
You can;
if isobject(conn) then
if not (conn Is Nothing) then set conn = nothing
end if
Use option explicit (each time a script runs without option explicit, a puppie dies out there), you probably would have detected the problem earlier as Nilpo mentioned.
When you dim a variable that you are going to use as an object reference and test it on Nothing, make it a habbit to set it to Nothing at initialization time(*): dim myObject : Set myObject = Nothing.
(*) Not really at initialization, because the dim's are handled before a routine starts, but when you put all your dim's at the top of a routine, it will practically be the same.
Use the IsNothing function. You should also check that it is an object.
sub cleanUp()
if Not IsNothing(conn) then
if IsObject(conn) then
conn.Close
end if
set conn = nothing
end if
end sub
That being said, I would do it like this since setting a variable to nothing does no harm.
sub cleanUp()
if IsObject(conn) then
conn.Close
end if
set conn = nothing
end sub
More importantly though, your problem is that conn is not in scope for your subroutine. You should probably pass it in as a parameter.

Classic asp - response.redirect in a sub - error handling

I wish to do the following ... Provide a page a developer can redirect to provided an error occurs ... like a vb error connection couldn't open or object couldn't be found ... or a database error is raised ... but since I moved the redirect into a sub the page doesn't actually redirect ... Is it possible that I simply can't redirect from a sub? Seems weird.
Run a stored procedure that raises an error
Dim cmd
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "spReturnDBException"
cmd.Execute
Call a handle errors function that sets up some session parms and redirects if neccessary
HandleErrors con _
, Request.ServerVariables("PATH_INFO") _
, "An error occurred while trying to save sessions." _
, "Actual Error: " + Err.Description + " EmpNo: " + Session("EmpNo") _
+ ". QueryString: " + Request.Querystring _
, 0
This would be the sub called.
sub HandleErrors( connection, WebPagePath, GenericErrorMessage, DebugInfo, Severity)
//Check for vb errors
if Err.Number <> 0 Then
Session("WebPagePath") = WebPagePath
Session("SafeErrorMessage") = GenericErrorMessage 'Session("SafeErrorMessage") + "A connection was dropped while trying to complete sessions."
Session("DebugInfo") = DebugInfo ' Err.Description
Session("LineNo") = Err.Line
Session("StackTrace") = ""
Session("Severity") = Severity
response.redirect("Error.asp")
//error occurs
elseif connection.Errors.count <> 0 then
response.write("a database error occurred.")
// Store safe error message / # in session
Session("WebPagePath") = WebPagePath
Session("SafeErrorMessage") = GenericErrorMessage 'Session("SafeErrorMessage") + "An error has occurred while trying to save sessions."
Session("DebugInfo") = DebugInfo '"Some extra added debug info from the webpage"
Session("LineNo") = 0
Session("StackTrace") = ""
Session("Severity") = Severity
Dim objError
for each objError in connection.Errors
// Store safe error number in session
Session("SafeErrorNumbers") = Session("SafeErrorNumbers") + objError.Description
if connection.Errors.Count > 1 then
Session("SafeErrorNumbers") = Session("SafeErrorNumbers") + "|"
end if
next
response.Redirect("Error.asp")
end if
Err.Clear
end sub
To display the Error line number:
set objError = Server.GetLastError()
strErrorLine = objError.Line
Here are a couple threads on using Err.line:
http://www.daniweb.com/web-development/asp/threads/11615
http://www.sitepoint.com/forums/showthread.php?279612-ASP-Error-Handling.-Err.Line-weird-behavior
I can't explain why you are getting the results you are. I can tell you that if your code reachs a line that contains Response.Redirect that redirect will happen regardless of whether its a in a Sub procdure or not.
I would make this suggestion. Stop using using On Error Resume Next. It is very painful way to deal with exceptions.
Instead change HandleErrors into GenerateConnectionError. Its job would be to compose error source and description strings and deliberately call Err.Raise with a user define error number (I tend to use 1001).
Now your Error.asp should be installed in the root of your application as the handler for the 500.100 http status code. When a script error occurs IIS will look to the current error pages collection for the location to determine what to do. You will have set this to execute a URL and specified your Error.asp as the URL.
When Error.asp is executed it will find details about the page being requested from QueryString. Here you can also use Server.GetLastError to get an ASPError object from which you can get other details about the error.
Using this approach will detail with any script error without requiring the developer to remember to pepper their code with HandleError code. The developer need on remember to call GenerateConnectionError when performing code that is using an ADODB.Connection and even then you could probably abstract that inside an .asp include file.

Why do we get "Path not found" error while accessing vb code from classic asp page?

Could you please give your suggestions to the below problem:
I am working on a old project which was developed using traditional ASP and VB6.0.
I have registered the dll in component services. After creating the object in first line (in the code snippet below), when trying to call Login() method, it is giving the "Path not found" warning/error and I am not able to continue executing it further.
Thanks in advance for your consideration and help...also please let me know if you need more information...
SET objSecurity = Server.CreateObject( Application("APP_CLASS") & "Security" )
SET ox = new XMLTool
userID = uCase(userID)
dataXML = ""
IF objSecurity.Login( sessXML, userID, pwd, datXML ) Then
ox.LoadXML dataXML
..........
..........
"Path not found" is usually an IO exception. Does the objSecurity.Login() method read or write any data to a file or directory that does not exist? What is happening inside the objSecurity.Login() method?
Alternately, is there another "benign" method of the objSecurity object that you can call to verify that the object lives? Something like:
Dim sTest As String = objSecurity.Version()
or
Dim sTest As String = objSecurity.Name()
or even
Dim bExists As Boolean = (objSecurity IsNot Nothing)
I know that .ToString() didn't exist in VB6, but that's the idea.
Let's narrow down the problem to either objSecurity object itself, or something inside the .Login() method.

Resources