tasync_traceback.nim 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. discard """
  2. exitcode: 0
  3. output: "Matched"
  4. """
  5. import asyncdispatch, strutils
  6. # Tests to ensure our exception trace backs are friendly.
  7. # --- Simple test. ---
  8. #
  9. # What does this look like when it's synchronous?
  10. #
  11. # tasync_traceback.nim(23) tasync_traceback
  12. # tasync_traceback.nim(21) a
  13. # tasync_traceback.nim(18) b
  14. # Error: unhandled exception: b failure [OSError]
  15. #
  16. # Good (not quite ideal, but gotta work within constraints) traceback,
  17. # when exception is unhandled:
  18. #
  19. # <traceback for the unhandled exception>
  20. # <very much a bunch of noise>
  21. # <would be ideal to customise this>
  22. # <(the code responsible is in excpt:raiseExceptionAux)>
  23. # Error: unhandled exception: b failure
  24. # ===============
  25. # Async traceback
  26. # ===============
  27. #
  28. # tasync_traceback.nim(23) tasync_traceback
  29. #
  30. # tasync_traceback.nim(21) a
  31. # tasync_traceback.nim(18) b
  32. var result = ""
  33. proc b(): Future[int] {.async.} =
  34. if true:
  35. raise newException(OSError, "b failure")
  36. proc a(): Future[int] {.async.} =
  37. return await b()
  38. let aFut = a()
  39. try:
  40. discard waitFor aFut
  41. except Exception as exc:
  42. result.add(exc.msg & "\n")
  43. result.add("\n")
  44. # From #6803
  45. proc bar(): Future[string] {.async.} =
  46. await sleepAsync(100)
  47. if true:
  48. raise newException(OSError, "bar failure")
  49. proc foo(): Future[string] {.async.} = return await bar()
  50. try:
  51. result.add(waitFor(foo()) & "\n")
  52. except Exception as exc:
  53. result.add(exc.msg & "\n")
  54. result.add("\n")
  55. # Use re to parse the result
  56. import re
  57. const expected = """
  58. b failure
  59. Async traceback:
  60. tasync_traceback\.nim\(\d+?\) tasync_traceback
  61. tasync_traceback\.nim\(\d+?\) a \(Async\)
  62. tasync_traceback\.nim\(\d+?\) b \(Async\)
  63. Exception message: b failure
  64. bar failure
  65. Async traceback:
  66. tasync_traceback\.nim\(\d+?\) tasync_traceback
  67. tasync_traceback\.nim\(\d+?\) foo \(Async\)
  68. tasync_traceback\.nim\(\d+?\) bar \(Async\)
  69. Exception message: bar failure
  70. """
  71. # TODO: is asyncmacro good enough location for fooIter traceback/debugging? just put the callsite info for all?
  72. let resLines = splitLines(result.strip)
  73. let expLines = splitLines(expected.strip)
  74. when not defined(cpp): # todo fixme
  75. if resLines.len != expLines.len:
  76. echo("Not matched! Wrong number of lines!")
  77. echo expLines.len
  78. echo resLines.len
  79. echo("Expected: -----------")
  80. echo expected
  81. echo("Gotten: -------------")
  82. echo result
  83. echo("---------------------")
  84. quit(QuitFailure)
  85. var ok = true
  86. for i in 0 ..< resLines.len:
  87. if not resLines[i].match(re(expLines[i])):
  88. echo "Not matched! Line ", i + 1
  89. echo "Expected:"
  90. echo expLines[i]
  91. echo "Actual:"
  92. echo resLines[i]
  93. ok = false
  94. if ok:
  95. echo("Matched")
  96. else:
  97. quit(QuitFailure)
  98. else:
  99. echo("Matched")