You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Greg Stein <gs...@lyra.org> on 2000/07/18 10:25:24 UTC

error handling suggestion

Rather than use a callback for logging errors, why don't we just return the
data to the caller and let the caller decide?

Ryan's point about context is quite valid. It gets rather difficult to prep
the callback context for each of the calls into APR. But the *caller* of an
APR function knows the context. If not, then it just returns the data
further up until somebody does know.

When the caller gets an error, it can log the problem, or it can punt it up
to the next level.

I'll write a short design proposal here:

*) introduce an error structure:

   struct ap_error {
       ap_status_t status;
       const char * msg;
       struct ap_error * next;
   }

*) ->status contains the function result status. same as we return today.

*) ->msg contains descriptive text for the message

*) ->next is used to chain errors from low-level to high-level messages. For
   example, ap_write() returns { APR_ENOSPC, "out of space", NULL } (call it
   "error"). The caller creates a new error structure with { APR_ENOSPC,
   "could not PUT the resource.", error }. etc.
   
   The outermost ap_error_t contains a nice high-level description.
   Following the ->next pointer, we can find the low-level cause of the
   problem.

*) note that errors must be dynamically allocated. most APR functions have a
   pool that can be used. ->msg can typically be a const string, but if it
   must be constructed, then it would also use the pool.

*) there is a concern that a loop that generates/discards errors create an
   unbounded amount of memory. we could introduce an "error pool" in APR.
   this could be set on a per-thread (request) basis. if the app knows that
   it will be discarding errors within a loop, it could call ap_clear_pool()
   on the error pool to reset it.

*) msg could be left NULL, indicating that ap_strerror() should be used to
   get the message.

*) ap_error could have an "id" field added that allows for specification of
   where an error was generated. essentially a sub-status, but without the
   problems of overlapping ranges in ap_status_t values


Anyways... food for thought. I've used a structure similar to above in
mod_dav with great success. When the top-level gets an error, it just
iterates down the links dropping the items to the log. It is pretty cool
because you get a list from high-level down to low-level about the error.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: error handling suggestion

Posted by Jeff Trawick <tr...@bellsouth.net>.
(trying again after tweaking my mail cfg in various ways)

Greg Stein <gs...@lyra.org> writes:

> Rather than use a callback for logging errors, why don't we just return the
> data to the caller and let the caller decide?
> 
> Ryan's point about context is quite valid. It gets rather difficult to prep
> the callback context for each of the calls into APR. But the *caller* of an
> APR function knows the context. If not, then it just returns the data
> further up until somebody does know.
> 
> When the caller gets an error, it can log the problem, or it can punt it up
> to the next level.
> 
> I'll write a short design proposal here:
> ...

As far as I know this framework can be used to return whatever info
might be available.  

I'm concerned about the dynamic allocations from a pool.  This is
along the normal APR tact of forcing the app to have interesting pool
management code (like Apache), so I guess I should be used to it by
now :)

I'll also throw in the comment that the idea I described was tempered
by not wanting to throw out the current scheme but instead to try to
fill in some gaps here and there.   It is a bit hard to swallow the
changes required by your scheme at the moment :)

Have fun,

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

--IAA21049.964095755/k5.localdomain--


Re: error handling suggestion

Posted by Greg Stein <gs...@lyra.org>.
On Tue, Jul 18, 2000 at 11:49:35PM +0100, Tony Finch wrote:
> Greg Stein wrote:
> >
> >*) note that errors must be dynamically allocated. most APR functions have a
> >   pool that can be used. ->msg can typically be a const string, but if it
> >   must be constructed, then it would also use the pool.
> 
> In addition to what Ryan said, if a function returns NULL to indicate "no
> error" how does it indicate "no memory"?

exit()

:-)

Seriously, there are two ways this could be done:

1) there is the "out of mem" callback. that could "do something". no idea
   what, though.

2) the parameters in an out-of-mem error are fixed/constant. it would be
   entirely possible to "return &ap_nomem_error;". I said "dynamically
   allocated" simply on the assumption that people aren't going to be
   setting up a bazillion global/const ap_error structures. I also wanted to
   emphasize that returning a pointer to an automatic variable would be way
   wrong :-), and returning a structure itself would also be badness
   (because it makes it hard to link them together)


In sort: the out-of-mem can be handled. No big deal.

The real question is whether there is any possibly consensus on an error
structure nowadays.
[ the past is past; we are free to rearchitect if we so choose, and are
  willing to accept the dev hit. ]

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: error handling suggestion

Posted by rb...@covalent.net.
Greg,

What you are designing here, is the exact same structure that was rejected
almost two years ago.  This was the original design for the error
structure for Apache 2.0, except it has a next pointer.  This design was
ruled out because it generates error strings even when they may not be
wanted.  It was decided that even though this only impacted the error
case, it was a big enough impact to be a bad thing.

This decision was made by the group as a whole in late 1998 or early 1999.

The other suggestion at the time was to use a rich error value
(bitmask) to describe what went wrong.  Again, it was decided that was
overkill, and we just needed a simple integer.

With those two decisions, the only option left to us, is to add error
values.

I don't mind re-visiting the original design, but if we are going to do
that, let's at least look at the original design, because it was farily
well documented and fairly well thought out.  It was a complete design
that was made by Bill S., Ken C, Manoj and myself.

Ryan

On Tue, 18 Jul 2000, Greg Stein wrote:

> Rather than use a callback for logging errors, why don't we just return the
> data to the caller and let the caller decide?
> 
> Ryan's point about context is quite valid. It gets rather difficult to prep
> the callback context for each of the calls into APR. But the *caller* of an
> APR function knows the context. If not, then it just returns the data
> further up until somebody does know.
> 
> When the caller gets an error, it can log the problem, or it can punt it up
> to the next level.
> 
> I'll write a short design proposal here:
> 
> *) introduce an error structure:
> 
>    struct ap_error {
>        ap_status_t status;
>        const char * msg;
>        struct ap_error * next;
>    }

<snipped for brevity>

> Anyways... food for thought. I've used a structure similar to above in
> mod_dav with great success. When the top-level gets an error, it just
> iterates down the links dropping the items to the log. It is pretty cool
> because you get a list from high-level down to low-level about the error.
> 
> Cheers,
> -g
> 
> -- 
> Greg Stein, http://www.lyra.org/
> 


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: error handling suggestion

Posted by dean gaudet <dg...@arctic.org>.
On Tue, 18 Jul 2000, Tony Finch wrote:

> Greg Stein wrote:
> >
> >*) note that errors must be dynamically allocated. most APR functions have a
> >   pool that can be used. ->msg can typically be a const string, but if it
> >   must be constructed, then it would also use the pool.
> 
> In addition to what Ryan said, if a function returns NULL to indicate "no
> error" how does it indicate "no memory"?

does freebsd do optimistion memory allocation?  or is it like solaris and
requires you to allocate physical swap for every copy-on-write page of a
forked process?  (a total waste of several Gb of disk on every solaris web
server i've ever set up.)

linux does optimistic... which means out of memory gets signalled when the
system has no more swap left and it has to copy-on-write.  the process
gets a SIGBUS at this time (which is pretty pointless to handle, because
if you've driven the system into the ground the only choice you have is to
die.)

i kind of gave up on handling out of memory and just tune MaxClients
correctly for production.

-dean


Re: error handling suggestion

Posted by Tony Finch <do...@dotat.at>.
Greg Stein wrote:
>
>*) note that errors must be dynamically allocated. most APR functions have a
>   pool that can be used. ->msg can typically be a const string, but if it
>   must be constructed, then it would also use the pool.

In addition to what Ryan said, if a function returns NULL to indicate "no
error" how does it indicate "no memory"?

Tony.
-- 
f.a.n.finch    fanf@covalent.net    dot@dotat.at
421 manifold mosaic of the mundane