@@ -322,6 +322,65 @@ def CanEncode(self, clr_type):
322322
323323 PythonEngine . Exec ( PyCode ) ;
324324 }
325+
326+ const string TestExceptionMessage = "Hello World!" ;
327+ [ Test ]
328+ public void ExceptionEncoded ( )
329+ {
330+ PyObjectConversions . RegisterEncoder ( new ValueErrorCodec ( ) ) ;
331+ void CallMe ( ) => throw new ValueErrorWrapper ( TestExceptionMessage ) ;
332+ var callMeAction = new Action ( CallMe ) ;
333+ using var _ = Py . GIL ( ) ;
334+ using var scope = Py . CreateScope ( ) ;
335+ scope . Exec ( @"
336+ def call(func):
337+ try:
338+ func()
339+ except ValueError as e:
340+ return str(e)
341+ " ) ;
342+ var callFunc = scope . Get ( "call" ) ;
343+ string message = callFunc . Invoke ( callMeAction . ToPython ( ) ) . As < string > ( ) ;
344+ Assert . AreEqual ( TestExceptionMessage , message ) ;
345+ }
346+
347+ [ Test ]
348+ public void ExceptionDecoded ( )
349+ {
350+ PyObjectConversions . RegisterDecoder ( new ValueErrorCodec ( ) ) ;
351+ using var _ = Py . GIL ( ) ;
352+ using var scope = Py . CreateScope ( ) ;
353+ var error = Assert . Throws < ValueErrorWrapper > ( ( )
354+ => PythonEngine . Exec ( $ "raise ValueError('{ TestExceptionMessage } ')") ) ;
355+ Assert . AreEqual ( TestExceptionMessage , error . Message ) ;
356+ }
357+
358+ class ValueErrorWrapper : Exception
359+ {
360+ public ValueErrorWrapper ( string message ) : base ( message ) { }
361+ }
362+
363+ class ValueErrorCodec : IPyObjectEncoder , IPyObjectDecoder
364+ {
365+ public bool CanDecode ( PyObject objectType , Type targetType )
366+ => this . CanEncode ( targetType ) && objectType . Equals ( PythonEngine . Eval ( "ValueError" ) ) ;
367+
368+ public bool CanEncode ( Type type ) => type == typeof ( ValueErrorWrapper )
369+ || typeof ( ValueErrorWrapper ) . IsSubclassOf ( type ) ;
370+
371+ public bool TryDecode < T > ( PyObject pyObj , out T value )
372+ {
373+ var message = pyObj . GetAttr ( "args" ) [ 0 ] . As < string > ( ) ;
374+ value = ( T ) ( object ) new ValueErrorWrapper ( message ) ;
375+ return true ;
376+ }
377+
378+ public PyObject TryEncode ( object value )
379+ {
380+ var error = ( ValueErrorWrapper ) value ;
381+ return PythonEngine . Eval ( "ValueError" ) . Invoke ( error . Message . ToPython ( ) ) ;
382+ }
383+ }
325384 }
326385
327386 /// <summary>
0 commit comments