Forum OpenACS Q&A: GetRow Called outside fetch Loop?

Collapse
Posted by Chris Hardy on
Well, in my quest to get the Intranet Module to work (in between
School and Work, bleh) I've come across the following error, that's
got me pretty cranky.  I can't find the problem.. It's in the Spam
Module (this is a offshoot of the Daily Status Report Problem) Here's
the error log.

Errors since 29/Aug/2000:22:27:27

[29/Aug/2000:22:28:14]
    Error: Ns_PgGetRow(localhost::acsmajestic):  Get row called
outside
a fetch row loop.

[29/Aug/2000:22:28:14]
    Error: nsd.tcl: Database operation "getrow" failed
    Database operation "getrow" failed
        while executing
    "ns_db getrow $db $selection"
        invoked from within
    "while { [ns_db getrow $db $selection] } {

            set_variables_after_query

            # remove spaces from email address (since user
registration
doesn't cu ..."
        ("while" body line 101)
        invoked from within
    "while { 1 } {

        ns_log Notice "send_scheduled_spam_messages: checking
spam_history queue"

        ns_db dml $db "begin transaction"

        # Get a list of all s ..."
        (procedure "send_scheduled_spam_messages" line 33)
        invoked from within
    "send_scheduled_spam_messages"
        (file "/web/majestic/www/admin/spam/spam.tcl" line 150)
        invoked from within
    "source $script"
        invoked from within
    "if ![file exists $script] {
                ns_returnnotfound $conn
        } else {
                source $script
        }"
        (procedure "ns_sourceproc" line 3)
        invoked from within
    "ns_sourceproc cns5 {}"
    Notice: Querying 'update users
    set last_visit = sysdate()
    where user_id = 6;'

Now, from what I've been able to to piece together, It should return
e-mail addresses, and then they get cleansed for white space.  Can
this Error be caused because the getrow is returning null?  I'm gonna
be placing a couple of ns_log Debug "Variable = $variable" statements
in the code. But can anyone help me along here?

Collapse
Posted by Dan Wickstrom on
I'm unable to recreate the problem on my development machine.  Could you give some more details, so that I could recreate the problem?  Also when you insert log information, could you select HTML format and surround the log entry with <pre> and </pre> so that it retains its format?
Collapse
Posted by Chris Hardy on
Ok, I'll Remember the Tags. Anyways, the way to re-create this problem is. Fire up the Intranet Module, add some employees (I've currently got 5 in my list), Then Create a Employee Group in the user groups. Go over to the /admin/spam directory, Add a file called intranetstatus, mine is
     Dear $first_names,

     The following is summary of the previous day at MajesticWorks.  You may view this online at [im_url]/status-report.tcl

     [im_status_report $db 1 "" "email_summary"]
Then Select the User Class for your employees, have subject like MajesticWorks Status for %%DATE%% stick intranetstatus for the Filename, make the Frequency Daily and make it a template.. Few minutes later, you might get an error. >:)
Collapse
Posted by Dan Wickstrom on
There should be a Notice message in the log right before the point where the error occurs.  The notice message should begin with:

Notice: spam user class query...

What does this log message look like in your log file?

Collapse
Posted by Chris Hardy on
Well, Since I've been working out bugs, I've got Crazy Debug logging going on, So here's The SQL it executes as well..
[29/Aug/2000:22:57:40][15121.11268][-sched:93-] Notice: spam user class query: select email_type,  users.approved_date, users.approving_note, users.approving_user, users.banned_date, users.banning_note, users.banning_user, users.bio, users.converted_p, users.crm_state, users.crm_state_entered_date, users.deleted_date, users.deleting_note, users.deleting_user, users.email, users.email_bouncing_p, users.email_verified_date, users.first_names, users.last_name, users.last_visit, users.lob, users.n_sessions, users.on_vacation_until, users.password, users.portrait_client_file_name, users.portrait_comment, users.portrait_file_extension, users.portrait_file_type, users.portrait_original_height, users.portrait_original_width, users.portrait_thumbnail_height, users.portrait_thumbnail_width, users.portrait_upload_date, users.priv_email, users.priv_name, users.registration_date, users.registration_ip, users.rejected_date, users.rejecting_note, users.rejecting_user, users.screen_name, users.second_to_last_visit, users.url, users.user_id, users.user_state from users_spammable users
where ad_group_member_p(users.user_id, 8) = 't'
                
        order by users.user_id
I've also added a ns_log Debug That grabs the $db and $selection variables for that query.. Though I'm scratching my head about it.. Here's the output.
29/Aug/2000:22:57:40][15121.11268][-sched:93-] Debug: db = nsdb0 selection = t28
Collapse
Posted by Dan Wickstrom on
The problem is that your template is referencing the same db handle as the one that is being used for the fetchrow loop.  If you remove the [im_status_report ... line from the intranetstatus file, the problem should go away.  I haven't tried it, but there is also another handle available inside the fetchrow loop and it doesn't appear to be in use.  You could try changing your template to use:

[im_status_report $db2 ...

Collapse
Posted by Michael A. Cleverly on
I've also added a ns_log Debug That grabs the $db and $selection variables for that query.. Though I'm scratching my head about it.. Here's the output.

29/Aug/2000:22:57:40][15121.11268][-sched:93-] Debug: db = nsdb0 selection = t28

Were you expecting to see all the key/value pairs for the selection ns_set? If so, you should use the command ns_set print $selection to write the key/value pairs of the selection ns_set to your log file.

Collapse
Posted by Dan Wickstrom on
tcl stores pointers to structures in a hash table, and it uses strings to reference these structures.  So in this case "nsdb0" references a long pointer that refers to the actual db handle structure.  The same is true for the "t28" label which is used to look up the actual pointer to the corresponding ns_set structure.  The hash table that is used to look up the values of "t28" and "nsdb0" corresponds to the local namespace.  A seperate hash table is also maintained by the tcl interpreter for the global namespace.
Collapse
Posted by Chris Hardy on
Well, as of right now, everything looks good.  Hopefully that fixes the ad_sec_user_id stuff as well. Thanks Dan and Michael, I've got some more info to use troubleshooting as well!
Collapse
Posted by Dan Wickstrom on
Did using $db2 in your template fix the problem?
Collapse
Posted by Chris Hardy on
I'll know tonight when it runs.  It fixed the Send a spam right now option.. I'll let you know.
Collapse
Posted by Chris Hardy on
Well, I'm still getting the
Errors since 30/Aug/2000:23:57:29

[31/Aug/2000:00:06:03]
    Error: Tcl evaluator error in subst call for spam_id 47: can't read
"ad_sec_user_id": no such variable
    Aborting the sending of this spam.
    Notice: Querying 'update spam_history set
        n_sent = n_sent + 0 where spam_id = 47;'
Which I think is the spam module looking for my user id, but that makes no sense, as I'm not logged in, so it can't grab my cookie.
Collapse
Posted by Dan Wickstrom on
This is the section in spam-daemon.tcl that's giving the error:
	    if {[string match $template_p "t"]} {
		if {[catch {
		    set message_body [subst $message_body_template]
		    set title [subst $title]
		} errmsg]} {
		    ns_log Error "Tcl evaluator error in subst call for spam_id $spam_id: $errmsg
Aborting the sending of this spam."
		    break
		}
	     } else {
		 set message_body $message_body_template
	     }


So it looks like there is still a problem with your template. Have you changed your template? Try adding a ns_log message in spam-daemon.tcl to output $message_body_template. The template probably references ad_sec_user_id or calls a routine that references it. It's probably called from inside of im_status_report somewhere.
Collapse
Posted by Chris Hardy on
Here's the Result of the debug Message
[31/Aug/2000:13:28:02][19454.10244][-sched:93-] Debug: Dear $first_names,

The following is summary of the previous day at MajesticWorks.  You may
view this online at [im_url]/status-report.tcl

[im_status_report $db 2 "" "email_summary"]
------- Removal instructions ------
http://acs.majesticworks.com//pvt/home.tcl

Notice that it reports $db 2 Yet, in my intranetstatus file it shows.
Dear $first_names,

The following is summary of the previous day at MajesticWorks.  You may
view this online at [im_url]/status-report.tcl

[im_status_report $db2 1 "" "email_summary"]


So now I'm even more confused (I restarted the server, etc).
Collapse
Posted by Dan Wickstrom on
I believe that it stuffs your template into the db, so the change you made to intranetstatus probably doesn't get put into the db again unless you go through the spam file add routine.  Try deleting your file using the spam admin pages, and then go ahead and do the file upload again.
Collapse
Posted by Chris Hardy on
Works like a charm! Thanks!
Collapse
Posted by Chris Hardy on
Spoke to fast Once again I got the
Errors since 01/Sep/2000:00:19:15

[01/Sep/2000:00:20:07]
    Error: Tcl evaluator error in subst call for spam_id 50: can't read
"ad_sec_user_id": no such variable
    Aborting the sending of this spam.
    Notice: Querying 'update spam_history set
        n_sent = n_sent + 0 where spam_id = 50;'
I went and looked in my log's, and gto
[01/Sep/2000:00:20:06][20246.69636][-sched:93-] Debug: db = nsdb0 selection = t10
[01/Sep/2000:00:20:06][20246.69636][-sched:93-] Debug: 

Dear $first_names,

The following is summary of the previous day at MajesticWorks.  You may
view this online at [im_url]/status-report.tcl

[im_status_report $db2 1 "" "email_summary"]



------- Removal instructions ------
http://acs.majesticworks.com//pvt/home.tcl
Now what exactly is the purpose of the subst call? It seems to be the culprate that is causing problems. I looked at bboards and it calls
       if [catch { ns_sendmail $email $maintainer_email "$topic forum $frequency summary" $msg_body $extraheaders} errmsg] {
Sendmail directly, and never runs the statements through subst. Something in this call is looking for the user cookie, and since no-one is logged in, it's failing.. Any ideas?
Collapse
Posted by Dan Wickstrom on
The subst call takes your template and does variable, function, and backslash substitution on it.  I suspect that one of the routines that is called by im_status_report must be trying to access ad_sec_user_id.  You might have to settle for putting just a link to the status report in your spam template.  If you really want this to work, you could try digging into im_status_report.  im_status_report has a list of routines that it evals to form the overall report.  It's probable that one of those subroutines uses ad_sec_user_id.  It seems that wherever user_id is needed in intranet-defs.tcl, there is an access to ad_sec_user_id.