ASP VBScript fails when response.buffer = True

J

Jim Rodgers

I have a big asp file that has an error under certain conditions -- totally
repeatable. However, it only fails when I set response.buffer = True at the
top. WHen I set it False in order to debug it, it works every time! I even
set it to True, but did a .Flush just before the error, and the error won't
happen.

It only happens when response.buffer is True and no .response.flush is issued.

The error is a string variable turns-up empty and crashes a function
requiring a date. I could test for this before the line where it crashes,
but where did my data go? Why is the buffer affecting it?

Bewilderedness!
 
A

Anthony Jones

Jim Rodgers said:
I have a big asp file that has an error under certain conditions -- totally
repeatable. However, it only fails when I set response.buffer = True at the
top. WHen I set it False in order to debug it, it works every time! I even
set it to True, but did a .Flush just before the error, and the error won't
happen.

It only happens when response.buffer is True and no .response.flush is issued.

The error is a string variable turns-up empty and crashes a function
requiring a date. I could test for this before the line where it crashes,
but where did my data go? Why is the buffer affecting it?

Bewilderedness!

Certainly is. Especially since you haven't stated exactly what the error is
and posted a code snippet of where it is failing.

Are you using IIS6 or 5?
 
J

Jim Rodgers

"The error is a string variable turns-up empty and crashes a function
requiring a date."

"It only happens when response.buffer is True and no .response.flush is
issued."

—

And here's the code where it fails:

<div> <%=FormatDateTime(strManifestDate,2)%> </div>

It fails because strManifestDate is empty. It is as if the buffer=true
setting changes the execution order of the VBScript code. The exact same
test case where this happens NEVER fails when buffer=false.

The only script functions are javascript one-liners triggered by DHTML
events. None of the scripts processes strManifestDate, and all of them cause
the current page to exit. It seems these are not the root cause of the empty
variable.

My next debug attempt will be to write debug statements to the IIS Log
instead of the HTML output stream. Perhaps this will reveal how this
variable winds up empty when buffer=true.

(NOTE: When buffer=true, debugging with response.write does not work, of
course: the server script fails before outputting anything. This is an
excellent example of the Heisenberg Uncertainty Principle!)

Does this help anyone understand the mystery? I really need the extra
performance from buffer=true, so I can't simply turn it off and move on.

— Jim
 
B

Bob Barrows [MVP]

Jim said:
"The error is a string variable turns-up empty and crashes a function
requiring a date."

"It only happens when response.buffer is True and no .response.flush
is issued."

-

And here's the code where it fails:

<div> <%=FormatDateTime(strManifestDate,2)%> </div>
LOL
Do you really expect us to be able to reproduce or diagnose your
symptoms based on this???
At least tell us how strManifestDate is defined.
It fails because strManifestDate is empty. It is as if the
buffer=true setting changes the execution order of the VBScript code.
The exact same test case where this happens NEVER fails when
buffer=false.
Take everything else out of the page except the stuff that has to do
with strManifestDate. Test it with both buffer settings and make sure it
works. Then incrementally add stuff back in until setting buffer to true
causes it to fail. Tell us what you added that makes it fail.

Bob Barrows
 
B

Bob Barrows [MVP]

Jim said:
"The error is a string variable turns-up empty and crashes a function
requiring a date."

"It only happens when response.buffer is True and no .response.flush
is issued."

-

And here's the code where it fails:

<div> <%=FormatDateTime(strManifestDate,2)%> </div>

Just to clarify: start with this:

<%Response.Buffer=true%>
<%
dim strManifestDate
strManifestDate=now
%>
<HTML>
<BODY>
<div><%=FormatDateTime(strManifestDate,2)%></div>
</BODY>
</HTML>

Verify that it works and then add functionality in increments until it
stops working. Show us what makes it stop working.
 
D

Dave Anderson

Jim said:
NOTE: When buffer=true, debugging with response.write does not
work, of course: the server script fails before outputting
anything.

Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]
 
J

Jim Rodgers

Dave,

Thank you for offering to help!

You asked...
Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]

The answer is: with buffer=true, what you show here works.
But if you comment out the .Flush, it fails! The .Flush, which
was added for debugging the [line that causes error], prevents
the error I'm debugging!

One more comment: in the [line that causes error], I output
the function using the <%=expression%> technique. I freely
mix this with the Response.Write method throughout.

It is reminiscent of a multiprocess race hazard: as if .Flush
synchronizes something somehow. For example, does ASP
process the HTML code (including <%=expression%> tags)
in some way before running the ASP script, per se?

In the past with .html files, I've seen "out of sequence"
mysteries when there was an error in <TR> and <TD> tags
causing something "later" to appear "earlier."

The culprit variable, strManifestNum, is assured of
getting set to a date way early in the code. It seems
impossible that simply running buffer=true would cause
the expression to be evaluated before its constituent
variable, strManifestNum, is evaluated.

There are a thousand lines in this asp file. And I can't go
back to a version that "worked" because I found this while
running test cases in final QA. The test case that fails
requires much of this code, so I can't just start hacking off
limbs to see who's throwing the bad pitch.

I might have found this problem sooner if I had buffer=true
during development. But I typically set this just before I
run final QA.

Thanks for your time.

— Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


Dave Anderson said:
Jim said:
NOTE: When buffer=true, debugging with response.write does not
work, of course: the server script fails before outputting
anything.

Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms.
 
A

Anthony Jones

Jim Rodgers said:
Dave,

Thank you for offering to help!

You asked...
Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]

The answer is: with buffer=true, what you show here works.
But if you comment out the .Flush, it fails! The .Flush, which
was added for debugging the [line that causes error], prevents
the error I'm debugging!

One more comment: in the [line that causes error], I output
the function using the <%=expression%> technique. I freely
mix this with the Response.Write method throughout.

It is reminiscent of a multiprocess race hazard: as if .Flush
synchronizes something somehow. For example, does ASP
process the HTML code (including <%=expression%> tags)
in some way before running the ASP script, per se?

In the past with .html files, I've seen "out of sequence"
mysteries when there was an error in <TR> and <TD> tags
causing something "later" to appear "earlier."

The culprit variable, strManifestNum, is assured of
getting set to a date way early in the code. It seems
impossible that simply running buffer=true would cause
the expression to be evaluated before its constituent
variable, strManifestNum, is evaluated.

There are a thousand lines in this asp file. And I can't go
back to a version that "worked" because I found this while
running test cases in final QA. The test case that fails
requires much of this code, so I can't just start hacking off
limbs to see who's throwing the bad pitch.

I might have found this problem sooner if I had buffer=true
during development. But I typically set this just before I
run final QA.

Thanks for your time.

I think this 'executing out of order' theory highly unlikely. The only case
I know where this _appears_ to happen is mixing serverside script languages.

Can we just check that the basics are in place.

Everything is VBScript? (You haven't got <script runat="server" elements)

Option Explicit is the first line of code?
Response.Buffer = True is the next?

You've searched for strManifestNum and it is assigned once before use?
strManifestNum is not passed by reference to other functions?
Are there no include files that may be modifying it?

- Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


Dave Anderson said:
Jim said:
NOTE: When buffer=true, debugging with response.write does not
work, of course: the server script fails before outputting
anything.

Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms.
 
J

Jim Rodgers

Thanks, Anthony.

It's hard for me to believe this, but I dropped Option Explicit
a while back while cutting and pasting code chunks into include
files, and I never put it back!!!

So I found numerous minor errors, and possibly some major
ones. The culprit variable was not declared, but it also was
not involved in any blatant outrageous mistakes that I have
found yet.

However, I have found more than one place where I
misspelled an ADO constant, using "adoCmdText" and
"adoCmdStoredProc" instead of "adCmd...". Interestingly,
fixing these broke the code in at least one new place.

Considering that the test case cannot run with these
"new" bugs, you may have steered me to a series of
mistakes I normally would have found [w/ Option Explicit].

I can't believe I did this. Anyway, for the record, here's
the code at the top of the file:



<% @EnableSessionState=False %>
<% Option Explicit %>
<% Response.Buffer = TRUE %>
<%
'
Dim blndebug
blndebug = False
'
'=========================
' C:\Program Files\Common Files\System\ADO\msado15.dll
%>
<!--
METADATA
TYPE="typelib"
uuid="2A75196C-D9EB-4129-B803-931327F72D5C"
NAME="Microsoft ActiveX Data Objects 2.8 Library"
-->
<%
'=========================
'


To address your other questions, none of the includes uses
the culprit variable. That variable is assigned in many places
and in many ways. My larger asp files use blnDebug to gate
Response.Writes of certain variables for debugging. When
blnDebug=True and Response.Buffer=False, I can see this
variable go through its paces just fine. (But turn the buffer
on, and -Boom-)

Finally, I haven't used runat="server" in ten years. I had
forgotten all about that one.

Meanwhile, I have somecode to edit and review. I'll post
again after I can run the test case again.

Thanks,

— Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


Anthony Jones said:
Jim Rodgers said:
Dave,

Thank you for offering to help!

You asked...
Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]

The answer is: with buffer=true, what you show here works.
But if you comment out the .Flush, it fails! The .Flush, which
was added for debugging the [line that causes error], prevents
the error I'm debugging!

One more comment: in the [line that causes error], I output
the function using the <%=expression%> technique. I freely
mix this with the Response.Write method throughout.

It is reminiscent of a multiprocess race hazard: as if .Flush
synchronizes something somehow. For example, does ASP
process the HTML code (including <%=expression%> tags)
in some way before running the ASP script, per se?

In the past with .html files, I've seen "out of sequence"
mysteries when there was an error in <TR> and <TD> tags
causing something "later" to appear "earlier."

The culprit variable, strManifestNum, is assured of
getting set to a date way early in the code. It seems
impossible that simply running buffer=true would cause
the expression to be evaluated before its constituent
variable, strManifestNum, is evaluated.

There are a thousand lines in this asp file. And I can't go
back to a version that "worked" because I found this while
running test cases in final QA. The test case that fails
requires much of this code, so I can't just start hacking off
limbs to see who's throwing the bad pitch.

I might have found this problem sooner if I had buffer=true
during development. But I typically set this just before I
run final QA.

Thanks for your time.

I think this 'executing out of order' theory highly unlikely. The only case
I know where this _appears_ to happen is mixing serverside script languages.

Can we just check that the basics are in place.

Everything is VBScript? (You haven't got <script runat="server" elements)

Option Explicit is the first line of code?
Response.Buffer = True is the next?

You've searched for strManifestNum and it is assigned once before use?
strManifestNum is not passed by reference to other functions?
Are there no include files that may be modifying it?

- Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


Dave Anderson said:
Jim Rodgers wrote:
NOTE: When buffer=true, debugging with response.write does not
work, of course: the server script fails before outputting
anything.

Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms.
 
J

Jim Rodgers

Well, Dang.

Problem is still there.

If I take out the Response.Flush that's just before
the "line that fails," that's when it fails. Leave the
Response.Flush in, and the line works.

Here's the actual code...

<td width="0" >
<div style="color: #800000"><%=Controls(intState,2,9)%></div>
<% 'response.flush
'response.write "strManifestDate = """ & strManifestDate & """" %>
<div <%=Controls(intState,4,9)%>
class=dropdowns style="height: 15px; border: 1px inset black;">
<%=FormatDateTime(strManifestDate,2)%>
</div>
</td>


All those <%=Controls(intState,2,9)%> things
you see are a system I use to specify stuff like
"DISABLED" or "onClick" depending on page
state and which control, etc.

The offending line is this:

<%=FormatDateTime(strManifestDate,2)%>

The famous culprit variable is strManifestDate.
If I unwrap it from the FormatDateTime()
function and put it alobe in the DIC, then I see
that it is an empty string when the program fails.
Hence the following error code:

Error Type:
Microsoft VBScript runtime (0x800A000D)
Type mismatch: 'FormatDateTime'

Any ideas?

— Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


Jim Rodgers said:
Thanks, Anthony.

It's hard for me to believe this, but I dropped Option Explicit
a while back while cutting and pasting code chunks into include
files, and I never put it back!!!

So I found numerous minor errors, and possibly some major
ones. The culprit variable was not declared, but it also was
not involved in any blatant outrageous mistakes that I have
found yet.

However, I have found more than one place where I
misspelled an ADO constant, using "adoCmdText" and
"adoCmdStoredProc" instead of "adCmd...". Interestingly,
fixing these broke the code in at least one new place.

Considering that the test case cannot run with these
"new" bugs, you may have steered me to a series of
mistakes I normally would have found [w/ Option Explicit].

I can't believe I did this. Anyway, for the record, here's
the code at the top of the file:



<% @EnableSessionState=False %>
<% Option Explicit %>
<% Response.Buffer = TRUE %>
<%
'
Dim blndebug
blndebug = False
'
'=========================
' C:\Program Files\Common Files\System\ADO\msado15.dll
%>
<!--
METADATA
TYPE="typelib"
uuid="2A75196C-D9EB-4129-B803-931327F72D5C"
NAME="Microsoft ActiveX Data Objects 2.8 Library"
-->
<%
'=========================
'


To address your other questions, none of the includes uses
the culprit variable. That variable is assigned in many places
and in many ways. My larger asp files use blnDebug to gate
Response.Writes of certain variables for debugging. When
blnDebug=True and Response.Buffer=False, I can see this
variable go through its paces just fine. (But turn the buffer
on, and -Boom-)

Finally, I haven't used runat="server" in ten years. I had
forgotten all about that one.

Meanwhile, I have somecode to edit and review. I'll post
again after I can run the test case again.

Thanks,

— Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


Anthony Jones said:
Jim Rodgers said:
Dave,

Thank you for offering to help!

You asked...

Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]


The answer is: with buffer=true, what you show here works.
But if you comment out the .Flush, it fails! The .Flush, which
was added for debugging the [line that causes error], prevents
the error I'm debugging!

One more comment: in the [line that causes error], I output
the function using the <%=expression%> technique. I freely
mix this with the Response.Write method throughout.

It is reminiscent of a multiprocess race hazard: as if .Flush
synchronizes something somehow. For example, does ASP
process the HTML code (including <%=expression%> tags)
in some way before running the ASP script, per se?

In the past with .html files, I've seen "out of sequence"
mysteries when there was an error in <TR> and <TD> tags
causing something "later" to appear "earlier."

The culprit variable, strManifestNum, is assured of
getting set to a date way early in the code. It seems
impossible that simply running buffer=true would cause
the expression to be evaluated before its constituent
variable, strManifestNum, is evaluated.

There are a thousand lines in this asp file. And I can't go
back to a version that "worked" because I found this while
running test cases in final QA. The test case that fails
requires much of this code, so I can't just start hacking off
limbs to see who's throwing the bad pitch.

I might have found this problem sooner if I had buffer=true
during development. But I typically set this just before I
run final QA.

Thanks for your time.

I think this 'executing out of order' theory highly unlikely. The only case
I know where this _appears_ to happen is mixing serverside script languages.

Can we just check that the basics are in place.

Everything is VBScript? (You haven't got <script runat="server" elements)

Option Explicit is the first line of code?
Response.Buffer = True is the next?

You've searched for strManifestNum and it is assigned once before use?
strManifestNum is not passed by reference to other functions?
Are there no include files that may be modifying it?

- Jim

--
James W. (Jim) Rodgers, P.E., is a Senior Partner with General Consulting
Engineers, LLC, in Atlanta, Georgia.


:

Jim Rodgers wrote:
NOTE: When buffer=true, debugging with response.write does not
work, of course: the server script fails before outputting
anything.

Are you pairing that with Response.Flush()?

Response.Write(...)
Response.Flush()
[line that causes error]


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms.
 
J

Jim Rodgers

***** I FOUND IT. *****

Because of my going back and forth between
Buffer=True and False to debug various parts of
the code, I had to stop using Response.Redirect
to move to a new page or the same page in a
new state. (You can't use .Redirect and
..Buffer=False if you have already sent some of
the HTML out the door. So instead, I changed
to embedding a javascript in the HTML and
letting that redirect the page thus:

response.write "<SCRIPT language=javascript>" & vbCrLf
response.write " window.open('manifests.asp?','_top');" & vbCrLf
response.write "</SCRIPT>" & vbCrLf

However, in order for this to work, ASP had to
go ahead and render the whole page including
parts of the HTML that the client agent (browser)
would not have to render. So, it had to evaluate
a number of VBScript expressions involving
variables that I did not think I had to assure when
I was previously using .Redirect.

In each test case that failed, I had removed a
..Redirect and replaced it with an embedded
javascript window.open().

Now, with .Buffer=False or Response.Flush,
the javascript got to the browser *and* caused
a "redirect" before ASP had a chance to
finish calculating the current page all the way
down to where the error would occur.

What a stupid mistake!

Just imagine if I just set Buffer=False as a way
to fix this! It only worked in that case because
I was developing the asp on the same workstation.
In a production environment (or a proper test
instance environment), the error would have
occurred intermittently as server, browser, and
network response times varied.

Case solved.

Thanks to everyone for your help.

Cheers, Jim Rodgers
 
D

Dave Anderson

Jim said:
The offending line is this:

<%=FormatDateTime(strManifestDate,2)%>

The famous culprit variable is strManifestDate.
If I unwrap it from the FormatDateTime()
function and put it alobe in the DIC, then I see
that it is an empty string when the program fails.
Hence the following error code:

Error Type:
Microsoft VBScript runtime (0x800A000D)
Type mismatch: 'FormatDateTime'

Any ideas?

Yes - validate strManifestDate (or substitute a default) before you ever
reach this line. It is a required parameter for FormatDateTime:
http://msdn.microsoft.com/library/en-us/script56/html/1d3db34d-159e-45fc-b242-ae5d87d75725.asp

My VBScript is rusty, but this kind of thing ought to do:

Function DateFromString(D)
On Error Resume Next
DateFromString = DateValue(D)
If Err.Number > 0 Then
Err.Clear
DateFromString = Date
End If
On Error Goto 0
End Function

<%=FormatDateTime(DateFromString(strManifestDate),2)%>
 
D

Dave Anderson

Jim said:
***** I FOUND IT. *****
[redirection and buffering explanation trimmed]

This is among the many reasons I finish processing before doing anything
with the response stream. It is also justification for combining buffering
(the default anyway) with Response.Redirect when you decide to violate this
rule.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top