exception.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package python
  2. // See:
  3. // https://docs.python.org/3/c-api/exceptions.html
  4. import (
  5. "errors"
  6. )
  7. /*
  8. #define PY_SSIZE_T_CLEAN
  9. #include <Python.h>
  10. */
  11. import "C"
  12. func HasException() bool {
  13. return C.PyErr_Occurred() != nil
  14. }
  15. func GetError() error {
  16. if exception := FetchException(); exception != nil {
  17. return exception
  18. } else {
  19. return errors.New("Python error without an exception")
  20. }
  21. }
  22. //
  23. // Exception
  24. //
  25. type Exception struct {
  26. Type *Reference
  27. Value *Reference
  28. Traceback *Reference
  29. }
  30. func FetchException() *Exception {
  31. var type_, value, traceback *C.PyObject
  32. C.PyErr_Fetch(&type_, &value, &traceback)
  33. if type_ != nil {
  34. defer C.PyErr_Restore(type_, value, traceback)
  35. var type__, value_, traceback_ *Reference
  36. if type_ != nil {
  37. type__ = NewReference(type_)
  38. }
  39. if value != nil {
  40. value_ = NewReference(value)
  41. }
  42. if traceback != nil {
  43. traceback_ = NewReference(traceback)
  44. }
  45. return NewExceptionRaw(type__, value_, traceback_)
  46. } else {
  47. return nil
  48. }
  49. }
  50. func NewExceptionRaw(type_ *Reference, value *Reference, traceback *Reference) *Exception {
  51. return &Exception{
  52. Type: type_,
  53. Value: value,
  54. Traceback: traceback,
  55. }
  56. }
  57. // error signature
  58. func (self *Exception) Error() string {
  59. // TODO: include traceback?
  60. if self.Value != nil {
  61. return self.Value.String()
  62. } else if self.Type != nil {
  63. return self.Type.String()
  64. } else {
  65. return "malformed Python exception"
  66. }
  67. }
  68. func ClearException() {
  69. C.PyErr_Clear()
  70. }