I'd like to be able to prematurely end the thread of execution
within a Perl apache module from someplace *other than* the
PerlHandler entry point subroutine (usually "handler()").  That is,
when I'm a few subroutines deep inside my module, I want to be able
to spit out an error page and have the module finish as if handler()
had returned OK.  Right now I'm painstakingly propagating return
values back up to my handler() subroutine, but I'm hoping there's a
better way.

The ability to "finish" from any point in the path of execution is
something I'm used to from CGI.  If I'm having a problem at any
point in a CGI script, I can call an error page subroutine that
calls "exit()" at the very end, and be sure that the only thing that
will get sent to the browser is that error page.  Obviously I can't
use exit() in a Perl apache module, and Apache::exit() doesn't do
what I want either.  I don't want a 404 or a 500 or any other apache
error.  I want my error page to be taken as legitimate output (as if
my handler() routine had returned OK) and I want to be able to call
it from anywhere and have execution stop.

Some sample code further clarifying (I hope!) what I want to do:

---

# Inside Apache/MyModule.pm
...

# PerlHandler entry point
sub handler
{
  my($r) = shift;
  ...
  foo($r);
  goo($r);

  # Doing this--returning OK from with handler()--appears to be
  # the only way this module can finish "gracefully" with a
  # normal HTML page as the output.
  return OK;
}

sub foo
{
  ...
  do_something() || error_page();
  ...
}

sub goo
{
  ...
  # Send HTTP header and print an HTML page
  ...
}

sub error_page
{
  ...
  # Send HTTP header and print an HTML page with some error text
  ...
  # What goes here?  I want this to be the last thing run in
  # this module!  I don't want to return from foo() at all,
  # and I certainly don't want goo() to run and spew its own
  # output below the error page just printed.
}

...

---

When do_something() fails, I want error_page() to run and then I
want the handler to be finished.  The "What goes here?" bit would
be "exit" in a CGI script.

I just finished reading the O'Reilly book on Aapche Modules, and I
didn't find a solution there either.  It mentioned that die() would
propagate an error back to apache, but apparently they meant
"propagate" in the same way that return() "propagates" an error.
That is, die() is just an alternative to a return() from within
handler().  Calling die() form anyplace else causes a 500 error.  I
also tried explicitly setting the request object's status to OK
before die()ing or Apache::exit()ing but that didn't work either.

Any ideas?  Can this be done, or am I barking up the wrong tree?

-----------------+----------------------------------------
  John Siracusa  | If you only have a hammer, you tend to
 [EMAIL PROTECTED] | see every problem as a nail. -- Maslow

Reply via email to