Skip to Content.
Sympa Menu

freetds - Re: error handling mire

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Brian Bruns <camber AT ais.org>
  • To: "James K. Lowden" <jklowden AT speakeasy.org>
  • Cc: TDS Development Group <freetds AT franklin.metalab.unc.edu>
  • Subject: Re: error handling mire
  • Date: Sun, 25 Aug 2002 10:09:13 -0400 (EDT)


On Sun, 25 Aug 2002, James K. Lowden wrote:

> On Sat, 24 Aug 2002 20:39:57 -0400 (EDT), "Brian Bruns" <camber AT ais.org>
> wrote:
>
> > On Sat, 24 Aug 2002, James K. Lowden wrote:
> >
> > > I know, dbconvert() may be called with a NULL DBPROCESS*, and hence
> > > won't have a socket or a context, and a context is really handy to
> > > tds_client_msg(), because among other things it has a pointer to the
> > > user-defined error message handler. What dbconvert will have to do is
> > > make stuff up. It will have to construct a faux TDSSOCKET, gather the
> > > default TDSCONTEXT from global template created in dbinit(), and call
> > > tds_convert() with that.
> >
> > Just a pendantic point, TDSSOCKET * passed to tds_client_msg can be
> > NULL, so there is no need to dummy up anything. The subconverters can
> > similarly take a TDSCONTEXT * instead of TDSSOCKET.
>
> The user-defined error handler that tds_client_msg() calls may return
> nonzero. In that case, tds_client_msg() sets the socket state to
> TDS_DEAD. (Unfortunately, it hadn't been checking for a null socket, so
> that would have segfaulted, but I fixed that.) In the case of a null
> TDSSOCKET *, unsurprisingly, tds_client_msg() doesn't touch the socket:

To my knowledge, conversion errors never affect the socket state anyway.
Perhaps we should verify. I get convert errors all the time with bcp and
it blissfully continues afterwards.

> tds_client_msg(TDSCONTEXT *tds_ctx, TDSSOCKET *tds ...
> if(tds_ctx->err_handler) {
> ...
> ret = tds_ctx->err_handler(tds_ctx, tds, &msg_info);
> /* message handler returned FAIL/CS_FAIL
> ** mark socket as dead */
> if (ret && tds) {
> tds->state=TDS_DEAD;
> }
>
> If we don't pass a TDSSOCKET* (even an unconnected one) to tds_convert(),
> then it would not be available to pass to tds_client_msg(). tds_convert
> would have to pass a NULL TDSSOCKET* every time, and no user-handled
> conversion error would ever be able to affect the socket state.
>
> If there is *really* no socket (a NULL DBPROCESS*, say), my suggestion is
> to fake it. The underlying code will carefully set tds->state=TDS_DEAD,
> blissfully ignorant that the socket it's taking such good care of is a
> fiction provided by the API.

I don't like dummying up a socket, we should just test tds for NULL and
not preform any actions if it is. In ctlib there is no connection info
passed to cs_convert() *ever*, just a context. In dblib it's optional,
with the implied context. So, I just don't think a dummy socket is the
best way forward.

> While I think it's fine that tds_client_msg() accepts a null socket
> pointer, I don't think convert.c should discard/ignore a real one. I
> admit it's highly speculative that anyone has *ever* written an error
> handler that returned anything except zero, particularly for a conversion
> error. But in my free time I like to do the Right Thing just for the heck
> of it. :)

I'm just not certain it is the right thing. I'd like to feel out the
behaviour of dblib/ctlib a bit better wrt this before we make big changes.

> --jkl
>






Archive powered by MHonArc 2.6.24.

Top of Page