Ticket #36849: geoserrors.patch

File geoserrors.patch, 14.7 KB (added by David Smith, 2 days ago)
  • django/contrib/gis/geos/libgeos.py

    diff --git a/django/contrib/gis/geos/libgeos.py b/django/contrib/gis/geos/libgeos.py
    index feb225cf8c..7a5b11bdd0 100644
    a b def error_h(fmt, lst):  
    9797        err_msg = fmt % lst
    9898    except TypeError:
    9999        err_msg = fmt
    100     logger.error("GEOS_ERROR: %s\n", err_msg)
     100    from django.contrib.gis.geos.prototypes.threadsafe import thread_context
     101    thread_context.last_error = err_msg
    101102
    102103
    103104error_h = ERRORFUNC(error_h)
  • django/contrib/gis/geos/prototypes/errcheck.py

    diff --git a/django/contrib/gis/geos/prototypes/errcheck.py b/django/contrib/gis/geos/prototypes/errcheck.py
    index 044bf8bc5c..18839983a9 100644
    a b from ctypes import c_void_p, string_at  
    66
    77from django.contrib.gis.geos.error import GEOSException
    88from django.contrib.gis.geos.libgeos import GEOSFuncFactory
     9from django.contrib.gis.geos.prototypes.threadsafe import thread_context
    910
    1011# Getting the `free` routine used to free the memory allocated for
    1112# string pointers returned by GEOS.
    def check_dbl(result, func, cargs):  
    2425    """
    2526    # Checking the status code
    2627    if result != 1:
     28        thread_context.last_error = None
    2729        return None
    2830    # Double passed in by reference, return its value.
     31    thread_context.last_error = None
    2932    return last_arg_byref(cargs)
    3033
    3134
    3235def check_geom(result, func, cargs):
    3336    "Error checking on routines that return Geometries."
    3437    if not result:
    35         raise GEOSException(
    36             'Error encountered checking Geometry returned from GEOS C function "%s".'
    37             % func.__name__
     38        geos_msg = thread_context.last_error
     39        thread_context.last_error = None
     40
     41        error_msg = (
     42            f'Error encountered checking Geometry returned from GEOS C function '
     43            f'"{func.__name__}".'
    3844        )
     45        if geos_msg:
     46            error_msg = f"{error_msg} {geos_msg}"
     47        raise GEOSException(error_msg)
     48    thread_context.last_error = None
    3949    return result
    4050
    4151
    4252def check_minus_one(result, func, cargs):
    4353    "Error checking on routines that should not return -1."
    4454    if result == -1:
    45         raise GEOSException(
    46             'Error encountered in GEOS C function "%s".' % func.__name__
    47         )
     55        geos_msg = thread_context.last_error
     56        thread_context.last_error = None
     57
     58        error_msg = f'Error encountered in GEOS C function "{func.__name__}".'
     59        if geos_msg:
     60            error_msg = f"{error_msg} {geos_msg}"
     61        raise GEOSException(error_msg)
    4862    else:
     63        thread_context.last_error = None
    4964        return result
    5065
    5166
    5267def check_predicate(result, func, cargs):
    5368    "Error checking for unary/binary predicate functions."
    5469    if result == 1:
     70        thread_context.last_error = None
    5571        return True
    5672    elif result == 0:
     73        thread_context.last_error = None
    5774        return False
    5875    else:
    59         raise GEOSException(
    60             'Error encountered on GEOS C predicate function "%s".' % func.__name__
    61         )
     76        geos_msg = thread_context.last_error
     77        thread_context.last_error = None
     78
     79        error_msg = f'Error encountered on GEOS C predicate function "{func.__name__}".'
     80        if geos_msg:
     81            error_msg = f"{error_msg} {geos_msg}"
     82        raise GEOSException(error_msg)
    6283
    6384
    6485def check_sized_string(result, func, cargs):
    6586    """
    6687    Error checking for routines that return explicitly sized strings.
    6788
    6889    This frees the memory allocated by GEOS at the result pointer.
    6990    """
    7091    if not result:
    71         raise GEOSException(
    72             'Invalid string pointer returned by GEOS C function "%s"' % func.__name__
    73         )
     92        geos_msg = thread_context.last_error
     93        thread_context.last_error = None
     94
     95        error_msg = f'Invalid string pointer returned by GEOS C function "{func.__name__}"'
     96        if geos_msg:
     97            error_msg = f"{error_msg} {geos_msg}"
     98        raise GEOSException(error_msg)
    7499    # A c_size_t object is passed in by reference for the second
    75100    # argument on these routines, and its needed to determine the
    76101    # correct size.
    77102    s = string_at(result, last_arg_byref(cargs))
    78103    # Freeing the memory allocated within GEOS
    79104    free(result)
     105    thread_context.last_error = None
    80106    return s
    81107
    82108
    def check_string(result, func, cargs):  
    87113    This frees the memory allocated by GEOS at the result pointer.
    88114    """
    89115    if not result:
    90         raise GEOSException(
    91             'Error encountered checking string return value in GEOS C function "%s".'
    92             % func.__name__
     116        geos_msg = thread_context.last_error
     117        thread_context.last_error = None
     118
     119        error_msg = (
     120            f'Error encountered checking string return value in GEOS C function '
     121            f'"{func.__name__}".'
    93122        )
     123        if geos_msg:
     124            error_msg = f"{error_msg} {geos_msg}"
     125        raise GEOSException(error_msg)
    94126    # Getting the string value at the pointer address.
    95127    s = string_at(result)
    96128    # Freeing the memory allocated within GEOS
    97129    free(result)
     130    thread_context.last_error = None
    98131    return s
  • django/contrib/gis/geos/prototypes/threadsafe.py

    diff --git a/django/contrib/gis/geos/prototypes/threadsafe.py b/django/contrib/gis/geos/prototypes/threadsafe.py
    index d4f7ffb8ac..eedfc3f32a 100644
    a b class GEOSContextHandle(GEOSBase):  
    2020# to hold a reference to GEOSContextHandle for this thread.
    2121class GEOSContext(threading.local):
    2222    handle = None
     23    last_error = None
    2324
    2425
    2526thread_context = GEOSContext()
  • tests/gis_tests/data/geometries.json

    diff --git a/tests/gis_tests/data/geometries.json b/tests/gis_tests/data/geometries.json
    index 6856ac793a..a66ab14843 100644
    a b  
    1313  "errors": [
    1414    {"wkt": "GEOMETR##!@#%#............a32515", "bad": true, "hex": false, "msg": "String input unrecognized as WKT EWKT, and HEXEWKB."},
    1515    {"wkt": "Foo.Bar", "bad": true, "hex": false, "msg": "String input unrecognized as WKT EWKT, and HEXEWKB."},
    16     {"wkt": "POINT (5, 23)", "bad": true, "hex": false, "msg": "Error encountered checking Geometry returned from GEOS C function \"GEOSWKTReader_read_r\"."},
     16    {"wkt": "POINT (5, 23)", "bad": true, "hex": false, "msg": "Error encountered checking Geometry returned from GEOS C function \"GEOSWKTReader_read_r\". ParseException: Expected number but encountered ','"},
    1717    {"wkt": "AAABBBDDDAAD##@#1113511111-098111111111111111533333333333333", "bad": true, "hex": true, "msg": "String input unrecognized as WKT EWKT, and HEXEWKB."},
    18     {"wkt": "FFFFFFFFFFFFFFFFF1355555555555555555565111", "bad": true, "hex": true, "msg": "Error encountered checking Geometry returned from GEOS C function \"GEOSWKBReader_readHEX_r\"."},
     18    {"wkt": "FFFFFFFFFFFFFFFFF1355555555555555555565111", "bad": true, "hex": true, "msg": "Error encountered checking Geometry returned from GEOS C function \"GEOSWKBReader_readHEX_r\". ParseException: Unknown WKB type 535"},
    1919    {"wkt": "", "bad": true, "hex": false, "msg": "String input unrecognized as WKT EWKT, and HEXEWKB."}
    2020  ],
    2121  "wkt_out": [
Back to Top