Menu

#300 publicize TclWinConvertError and TclWinConvertWSAError

open
5
2003-09-04
2003-09-04
No

TclWinConvertError and TclWinConvertWSAError are
private internal functions. They could be very useful to
extension authors. I see a need for it. Let's make them
public.

Also, TclWinConvertWSAError doesn't map to all WSAE*
error codes. Included are mappings to all of them.
Unfortunetly, all the added can only return EINVAL until
the posix codes they translate into get more meaningful
to windows. Effectively, the behavior is still unchanged.

Example:

WSA_QOS_POLICY_FAILURE, 'rejected for administrative
reasons - bad credentials'
WSAEPROVIDERFAILEDINIT, 'The requested service
provider could not be loaded or initialized'

What posix codes do those get? Some detective work
needs to be done with these. I really don't have a clue.

The main reason I want to enlargen the mappings is to
include WSAHOST_NOT_FOUND. I hate that the
[socket] command can only return 'invalid argument'
instead of 'authoritative host not found' or 'try again',
or ....

Should this really be a TIP?

Discussion

  • David Gravereaux

    patch file #1

     
  • David Gravereaux

    Logged In: YES
    user_id=7549

    It would be nice also, if Tcl_ErrnoMsg() returned localized
    strings.

     
  • David Gravereaux

    Logged In: YES
    user_id=7549

    Please ignore that last post. That would break ALL scripts
    that did matching on error messages ;)

     
  • Don Porter

    Don Porter - 2003-09-05

    Logged In: YES
    user_id=80530

    Localized error messages are
    still a good idea, just one that needs
    to wait for a more thorough use of
    ::errorCode for script processing.
    jenglish and kbk both have ideas
    on this, but over a fairly extended
    time frame.

     
  • David Gravereaux

    Logged In: YES
    user_id=7549

    Here's another patch that adds Tcl_Win32Error(),
    Tcl_Win32ErrId(), Tcl_Win32ErrMsg(), and Tcl_Win32ErrMsgVA
    ().

    The concept of setting errno and returning from a function is
    usually then displayed to the user with Tcl_PosixError() in a
    generic layer for setting $errorCode. Tcl_Win32Error() is
    exactly analogous to that, except that it gets the error code
    from GetLastError() for the exact windows error.

    I would use this from an extension! See the shift? Instead of
    returning from a function with errno set, give the function the
    interp and let it set $errorCode itself. This concept is working
    well in a project I'm doing. NOTHING is getting lost in a
    translation as there aren't any to be made!

    Tcl_Win32ErrId() is 100% complete and match the october
    2002 release of the platform SDK. Error messages are asked
    for from the system with FormatMessage and could support
    localization...

    win/tclWinError.c builds with stock VC5, VC6, and with the
    platform SDK headers, too.

    my wrists are sore.. where's an ice pack in this house?

     
  • David Gravereaux

    patch file #2

     
  • David Gravereaux

    Logged In: YES
    user_id=7549

    Code could be added so that if Tcl(_)WinConvertError can't
    make the translation, the native message could be used
    instead.

    But Tcl is supposed to the great equilizer, and this new
    concept might be foriegn as it attemps to break from 'least
    common denominator' hole and might not be helpful for the
    places that are to provide a generic interface.

    In places where the native message is desirable, the ability to
    get it, is now easy.

     
  • David Gravereaux

    Logged In: YES
    user_id=7549

    Here's some code that shows how an extension could make
    use of this feature:

    CONST char *
    ExpWinExpError TCL_VARARGS_DEF(Tcl_Interp *, arg1)
    {
    CONST char *id, *msg;
    va_list argList;
    Tcl_Interp *interp;
    DWORD err = GetLastError();

    interp = TCL_VARARGS_START(Tcl_Interp *, arg1, argList);

    /*
    * If the "customer" bit is set, this error is ours. else
    forward
    * it to the system.
    */

    if (errorCode & (0x1 << 29)) {
    id = ExpWinExpErrId(err);
    msg = ExpWinExpErrMsgVA(err, argList);
    Tcl_SetErrorCode(interp, "EXPECT", id, msg, 0L);
    } else {
    id = Tcl_Win32ErrId(err);
    msg = Tcl_Win32ErrMsgVA(err, argList);
    Tcl_SetErrorCode(interp, "WIN32", id, msg, 0L);
    }
    va_end(argList);
    return msg;
    }