tasync_traceback.nim 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. asyncdispatch\.nim\(\d+?\) waitFor
  68. asyncdispatch\.nim\(\d+?\) poll
  69. ## Processes asynchronous completion events
  70. asyncdispatch\.nim\(\d+?\) runOnce
  71. asyncdispatch\.nim\(\d+?\) processPendingCallbacks
  72. ## Executes pending callbacks
  73. tasync_traceback\.nim\(\d+?\) bar \(Async\)
  74. Exception message: bar failure
  75. """
  76. # TODO: is asyncmacro good enough location for fooIter traceback/debugging? just put the callsite info for all?
  77. let resLines = splitLines(result.strip)
  78. let expLines = splitLines(expected.strip)
  79. when not defined(cpp): # todo fixme
  80. if resLines.len != expLines.len:
  81. echo("Not matched! Wrong number of lines!")
  82. echo expLines.len
  83. echo resLines.len
  84. echo("Expected: -----------")
  85. echo expected
  86. echo("Gotten: -------------")
  87. echo result
  88. echo("---------------------")
  89. quit(QuitFailure)
  90. var ok = true
  91. for i in 0 ..< resLines.len:
  92. if not resLines[i].match(re(expLines[i])):
  93. echo "Not matched! Line ", i + 1
  94. echo "Expected:"
  95. echo expLines[i]
  96. echo "Actual:"
  97. echo resLines[i]
  98. ok = false
  99. if ok:
  100. echo("Matched")
  101. else:
  102. quit(QuitFailure)
  103. else:
  104. echo("Matched")