@@ -63,6 +63,9 @@ typedef struct {
63
63
* was provided by librdkafka.
64
64
* Else falls back on err2str(). */
65
65
int fatal ; /**< Set to true if a fatal error. */
66
+ int retriable ; /**< Set to true if operation is retriable. */
67
+ int txn_abortable ; /**< Set to true if this is an abortable
68
+ * transaction error. */
66
69
} KafkaError ;
67
70
68
71
@@ -90,6 +93,18 @@ static PyObject *KafkaError_fatal (KafkaError *self, PyObject *ignore) {
90
93
return ret ;
91
94
}
92
95
96
+ static PyObject * KafkaError_retriable (KafkaError * self , PyObject * ignore ) {
97
+ PyObject * ret = self -> retriable ? Py_True : Py_False ;
98
+ Py_INCREF (ret );
99
+ return ret ;
100
+ }
101
+
102
+ static PyObject * KafkaError_txn_abortable (KafkaError * self , PyObject * ignore ) {
103
+ PyObject * ret = self -> txn_abortable ? Py_True : Py_False ;
104
+ Py_INCREF (ret );
105
+ return ret ;
106
+ }
107
+
93
108
94
109
static PyObject * KafkaError_test_raise_fatal (KafkaError * null ,
95
110
PyObject * ignore ) {
@@ -130,6 +145,21 @@ static PyMethodDef KafkaError_methods[] = {
130
145
{ "_test_raise_fatal" , (PyCFunction )KafkaError_test_raise_fatal ,
131
146
METH_NOARGS |METH_STATIC
132
147
},
148
+ { "retriable" , (PyCFunction )KafkaError_retriable , METH_NOARGS ,
149
+ " :returns: True if the operation that failed may be retried, "
150
+ "else False.\n"
151
+ " :rtype: bool\n"
152
+ "\n"
153
+ },
154
+ { "txn_abortable" , (PyCFunction )KafkaError_txn_abortable , METH_NOARGS ,
155
+ " :returns: True if the error is an abortable transaction error, "
156
+ "allowing the application to abort the current transaction with "
157
+ "abort_transaction() and start a new transaction with "
158
+ "begin_transaction(). This will only return true for errors from "
159
+ "the transactional producer API.\n"
160
+ " :rtype: bool\n"
161
+ "\n"
162
+ },
133
163
134
164
{ NULL }
135
165
};
@@ -274,6 +304,8 @@ static void KafkaError_init (KafkaError *self,
274
304
rd_kafka_resp_err_t code , const char * str ) {
275
305
self -> code = code ;
276
306
self -> fatal = 0 ;
307
+ self -> retriable = 0 ;
308
+ self -> txn_abortable = 0 ;
277
309
if (str )
278
310
self -> str = strdup (str );
279
311
else
@@ -319,6 +351,26 @@ PyObject *KafkaError_new0 (rd_kafka_resp_err_t err, const char *fmt, ...) {
319
351
}
320
352
321
353
354
+ /**
355
+ * @brief Create a KafkaError object from an rd_kafka_error_t *
356
+ * and destroy the C object when done.
357
+ */
358
+ PyObject * KafkaError_new_from_error_destroy (rd_kafka_error_t * error ) {
359
+ KafkaError * kerr ;
360
+
361
+ kerr = (KafkaError * )KafkaError_new0 (rd_kafka_error_code (error ),
362
+ "%s" ,
363
+ rd_kafka_error_string (error ));
364
+
365
+ kerr -> fatal = rd_kafka_error_is_fatal (error );
366
+ kerr -> retriable = rd_kafka_error_is_retriable (error );
367
+ kerr -> txn_abortable = rd_kafka_error_is_txn_abortable (error );
368
+ rd_kafka_error_destroy (error );
369
+
370
+ return (PyObject * )kerr ;
371
+ }
372
+
373
+
322
374
/**
323
375
* @brief Raise exception from fatal error.
324
376
*/
0 commit comments