tasync_traceback.nim 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. discard """
  2. exitcode: 0
  3. disabled: "windows"
  4. output: "Matched"
  5. """
  6. import asyncdispatch, strutils
  7. # Tests to ensure our exception trace backs are friendly.
  8. # --- Simple test. ---
  9. #
  10. # What does this look like when it's synchronous?
  11. #
  12. # tasync_traceback.nim(23) tasync_traceback
  13. # tasync_traceback.nim(21) a
  14. # tasync_traceback.nim(18) b
  15. # Error: unhandled exception: b failure [OSError]
  16. #
  17. # Good (not quite ideal, but gotta work within constraints) traceback,
  18. # when exception is unhandled:
  19. #
  20. # <traceback for the unhandled exception>
  21. # <very much a bunch of noise>
  22. # <would be ideal to customise this>
  23. # <(the code responsible is in excpt:raiseExceptionAux)>
  24. # Error: unhandled exception: b failure
  25. # ===============
  26. # Async traceback
  27. # ===============
  28. #
  29. # tasync_traceback.nim(23) tasync_traceback
  30. #
  31. # tasync_traceback.nim(21) a
  32. # tasync_traceback.nim(18) b
  33. var result = ""
  34. proc b(): Future[int] {.async.} =
  35. if true:
  36. raise newException(OSError, "b failure")
  37. proc a(): Future[int] {.async.} =
  38. return await b()
  39. let aFut = a()
  40. try:
  41. discard waitFor aFut
  42. except Exception as exc:
  43. result.add(exc.msg & "\n")
  44. result.add("\n")
  45. # From #6803
  46. proc bar(): Future[string] {.async.} =
  47. await sleepAsync(100)
  48. if true:
  49. raise newException(OSError, "bar failure")
  50. proc foo(): Future[string] {.async.} = return await bar()
  51. try:
  52. result.add(waitFor(foo()) & "\n")
  53. except Exception as exc:
  54. result.add(exc.msg & "\n")
  55. result.add("\n")
  56. # Use re to parse the result
  57. import re
  58. const expected = """
  59. b failure
  60. Async traceback:
  61. tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
  62. asyncmacro\.nim\(\d+?\)\s+?a
  63. asyncmacro\.nim\(\d+?\)\s+?aNimAsyncContinue
  64. ## Resumes an async procedure
  65. tasync_traceback\.nim\(\d+?\)\s+?aIter
  66. asyncmacro\.nim\(\d+?\)\s+?b
  67. asyncmacro\.nim\(\d+?\)\s+?bNimAsyncContinue
  68. ## Resumes an async procedure
  69. tasync_traceback\.nim\(\d+?\)\s+?bIter
  70. #\[
  71. tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
  72. asyncmacro\.nim\(\d+?\)\s+?a
  73. asyncmacro\.nim\(\d+?\)\s+?aNimAsyncContinue
  74. ## Resumes an async procedure
  75. tasync_traceback\.nim\(\d+?\)\s+?aIter
  76. asyncfutures\.nim\(\d+?\)\s+?read
  77. \]#
  78. Exception message: b failure
  79. Exception type:
  80. bar failure
  81. Async traceback:
  82. tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
  83. asyncdispatch\.nim\(\d+?\)\s+?waitFor
  84. asyncdispatch\.nim\(\d+?\)\s+?poll
  85. ## Processes asynchronous completion events
  86. asyncdispatch\.nim\(\d+?\)\s+?runOnce
  87. asyncdispatch\.nim\(\d+?\)\s+?processPendingCallbacks
  88. ## Executes pending callbacks
  89. asyncmacro\.nim\(\d+?\)\s+?barNimAsyncContinue
  90. ## Resumes an async procedure
  91. tasync_traceback\.nim\(\d+?\)\s+?barIter
  92. #\[
  93. tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
  94. asyncdispatch\.nim\(\d+?\)\s+?waitFor
  95. asyncdispatch\.nim\(\d+?\)\s+?poll
  96. ## Processes asynchronous completion events
  97. asyncdispatch\.nim\(\d+?\)\s+?runOnce
  98. asyncdispatch\.nim\(\d+?\)\s+?processPendingCallbacks
  99. ## Executes pending callbacks
  100. asyncmacro\.nim\(\d+?\)\s+?fooNimAsyncContinue
  101. ## Resumes an async procedure
  102. tasync_traceback\.nim\(\d+?\)\s+?fooIter
  103. asyncfutures\.nim\(\d+?\)\s+?read
  104. \]#
  105. Exception message: bar failure
  106. Exception type:
  107. """
  108. let resLines = splitLines(result.strip)
  109. let expLines = splitLines(expected.strip)
  110. if resLines.len != expLines.len:
  111. echo("Not matched! Wrong number of lines!")
  112. echo expLines.len
  113. echo resLines.len
  114. echo("Expected: -----------")
  115. echo expected
  116. echo("Gotten: -------------")
  117. echo result
  118. echo("---------------------")
  119. quit(QuitFailure)
  120. var ok = true
  121. for i in 0 ..< resLines.len:
  122. if not resLines[i].match(re(expLines[i])):
  123. echo "Not matched! Line ", i + 1
  124. echo "Expected:"
  125. echo expLines[i]
  126. echo "Actual:"
  127. echo resLines[i]
  128. ok = false
  129. if ok:
  130. echo("Matched")
  131. else:
  132. quit(QuitFailure)