test_trycatch.vim 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390
  1. " Test try-catch-finally exception handling
  2. " Most of this was formerly in test49.
  3. source check.vim
  4. source shared.vim
  5. source vim9.vim
  6. "-------------------------------------------------------------------------------
  7. " Test environment {{{1
  8. "-------------------------------------------------------------------------------
  9. com! XpathINIT let g:Xpath = ''
  10. com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
  11. " Test 25: Executing :finally clauses on normal control flow {{{1
  12. "
  13. " Control flow in a :try conditional should always fall through to its
  14. " :finally clause. A :finally clause of a :try conditional inside an
  15. " inactive conditional should never be executed.
  16. "-------------------------------------------------------------------------------
  17. func T25_F()
  18. let loops = 3
  19. while loops > 0
  20. Xpath 'a' . loops
  21. if loops >= 2
  22. try
  23. Xpath 'b' . loops
  24. if loops == 2
  25. try
  26. Xpath 'c' . loops
  27. finally
  28. Xpath 'd' . loops
  29. endtry
  30. endif
  31. finally
  32. Xpath 'e' . loops
  33. if loops == 2
  34. try
  35. Xpath 'f' . loops
  36. final
  37. Xpath 'g' . loops
  38. endtry
  39. endif
  40. endtry
  41. endif
  42. Xpath 'h' . loops
  43. let loops = loops - 1
  44. endwhile
  45. Xpath 'i'
  46. endfunc
  47. " Also try using "fina" and "final" and "finall" as abbreviations.
  48. func T25_G()
  49. if 1
  50. try
  51. Xpath 'A'
  52. call T25_F()
  53. Xpath 'B'
  54. fina
  55. Xpath 'C'
  56. endtry
  57. else
  58. try
  59. Xpath 'D'
  60. finall
  61. Xpath 'E'
  62. endtry
  63. endif
  64. endfunc
  65. func Test_finally()
  66. XpathINIT
  67. call T25_G()
  68. call assert_equal('Aa3b3e3h3a2b2c2d2e2f2g2h2a1h1iBC', g:Xpath)
  69. endfunc
  70. "-------------------------------------------------------------------------------
  71. " Test 26: Executing :finally clauses after :continue or :break {{{1
  72. "
  73. " For a :continue or :break dynamically enclosed in a :try/:endtry
  74. " region inside the next surrounding :while/:endwhile, if the
  75. " :continue/:break is before the :finally, the :finally clause is
  76. " executed first. If the :continue/:break is after the :finally, the
  77. " :finally clause is broken (like an :if/:endif region).
  78. "-------------------------------------------------------------------------------
  79. func T26_F()
  80. try
  81. let loops = 3
  82. while loops > 0
  83. try
  84. try
  85. if loops == 2
  86. Xpath 'a' . loops
  87. let loops = loops - 1
  88. continue
  89. elseif loops == 1
  90. Xpath 'b' . loops
  91. break
  92. finish
  93. endif
  94. Xpath 'c' . loops
  95. endtry
  96. finally
  97. Xpath 'd' . loops
  98. endtry
  99. Xpath 'e' . loops
  100. let loops = loops - 1
  101. endwhile
  102. Xpath 'f'
  103. finally
  104. Xpath 'g'
  105. let loops = 3
  106. while loops > 0
  107. try
  108. finally
  109. try
  110. if loops == 2
  111. Xpath 'h' . loops
  112. let loops = loops - 1
  113. continue
  114. elseif loops == 1
  115. Xpath 'i' . loops
  116. break
  117. finish
  118. endif
  119. endtry
  120. Xpath 'j' . loops
  121. endtry
  122. Xpath 'k' . loops
  123. let loops = loops - 1
  124. endwhile
  125. Xpath 'l'
  126. endtry
  127. Xpath 'm'
  128. endfunc
  129. func Test_finally_after_continue()
  130. XpathINIT
  131. call T26_F()
  132. call assert_equal('c3d3e3a2d1b1d1fgj3k3h2i1lm', g:Xpath)
  133. endfunc
  134. "-------------------------------------------------------------------------------
  135. " Test 32: Remembering the :return value on :finally {{{1
  136. "
  137. " If a :finally clause is executed due to a :return specifying
  138. " a value, this is the value visible to the caller if not overwritten
  139. " by a new :return in the :finally clause. A :return without a value
  140. " in the :finally clause overwrites with value 0.
  141. "-------------------------------------------------------------------------------
  142. func T32_F()
  143. try
  144. Xpath 'a'
  145. try
  146. Xpath 'b'
  147. return "ABCD"
  148. Xpath 'c'
  149. finally
  150. Xpath 'd'
  151. endtry
  152. Xpath 'e'
  153. finally
  154. Xpath 'f'
  155. endtry
  156. Xpath 'g'
  157. endfunc
  158. func T32_G()
  159. try
  160. Xpath 'h'
  161. return 8
  162. Xpath 'i'
  163. finally
  164. Xpath 'j'
  165. return 16 + strlen(T32_F())
  166. Xpath 'k'
  167. endtry
  168. Xpath 'l'
  169. endfunc
  170. func T32_H()
  171. try
  172. Xpath 'm'
  173. return 32
  174. Xpath 'n'
  175. finally
  176. Xpath 'o'
  177. return
  178. Xpath 'p'
  179. endtry
  180. Xpath 'q'
  181. endfunc
  182. func T32_I()
  183. try
  184. Xpath 'r'
  185. finally
  186. Xpath 's'
  187. return T32_G() + T32_H() + 64
  188. Xpath 't'
  189. endtry
  190. Xpath 'u'
  191. endfunc
  192. func Test_finally_return()
  193. XpathINIT
  194. call assert_equal(84, T32_I())
  195. call assert_equal('rshjabdfmo', g:Xpath)
  196. endfunc
  197. "-------------------------------------------------------------------------------
  198. " Test 33: :return under :execute or user command and :finally {{{1
  199. "
  200. " A :return command may be executed under an ":execute" or from
  201. " a user command. Executing of :finally clauses and passing through
  202. " the return code works also then.
  203. "-------------------------------------------------------------------------------
  204. func T33_F()
  205. try
  206. RETURN 10
  207. Xpath 'a'
  208. finally
  209. Xpath 'b'
  210. endtry
  211. Xpath 'c'
  212. endfunc
  213. func T33_G()
  214. try
  215. RETURN 20
  216. Xpath 'd'
  217. finally
  218. Xpath 'e'
  219. RETURN 30
  220. Xpath 'f'
  221. endtry
  222. Xpath 'g'
  223. endfunc
  224. func T33_H()
  225. try
  226. execute "try | return 40 | finally | return 50 | endtry"
  227. Xpath 'h'
  228. finally
  229. Xpath 'i'
  230. endtry
  231. Xpath 'j'
  232. endfunc
  233. func T33_I()
  234. try
  235. execute "try | return 60 | finally | return 70 | endtry"
  236. Xpath 'k'
  237. finally
  238. Xpath 'l'
  239. execute "try | return 80 | finally | return 90 | endtry"
  240. Xpath 'm'
  241. endtry
  242. Xpath 'n'
  243. endfunc
  244. func T33_J()
  245. try
  246. RETURN 100
  247. Xpath 'o'
  248. finally
  249. Xpath 'p'
  250. return
  251. Xpath 'q'
  252. endtry
  253. Xpath 'r'
  254. endfunc
  255. func T33_K()
  256. try
  257. execute "try | return 110 | finally | return 120 | endtry"
  258. Xpath 's'
  259. finally
  260. Xpath 't'
  261. execute "try | return 130 | finally | return | endtry"
  262. Xpath 'u'
  263. endtry
  264. Xpath 'v'
  265. endfunc
  266. func T33_L()
  267. try
  268. return
  269. Xpath 'w'
  270. finally
  271. Xpath 'x'
  272. RETURN 140
  273. Xpath 'y'
  274. endtry
  275. Xpath 'z'
  276. endfunc
  277. func T33_M()
  278. try
  279. return
  280. Xpath 'A'
  281. finally
  282. Xpath 'B'
  283. execute "try | return 150 | finally | return 160 | endtry"
  284. Xpath 'C'
  285. endtry
  286. Xpath 'D'
  287. endfunc
  288. func T33_N()
  289. RETURN 170
  290. endfunc
  291. func T33_O()
  292. execute "try | return 180 | finally | return 190 | endtry"
  293. endfunc
  294. func Test_finally_cmd_return()
  295. command! -nargs=? RETURN
  296. \ try | return <args> | finally | return <args> * 2 | endtry
  297. XpathINIT
  298. call assert_equal(20, T33_F())
  299. call assert_equal(60, T33_G())
  300. call assert_equal(50, T33_H())
  301. call assert_equal(90, T33_I())
  302. call assert_equal(0, T33_J())
  303. call assert_equal(0, T33_K())
  304. call assert_equal(280, T33_L())
  305. call assert_equal(160, T33_M())
  306. call assert_equal(340, T33_N())
  307. call assert_equal(190, T33_O())
  308. call assert_equal('beilptxB', g:Xpath)
  309. delcommand RETURN
  310. endfunc
  311. "-------------------------------------------------------------------------------
  312. " Test 41: Skipped :throw finding next command {{{1
  313. "
  314. " A :throw in an inactive conditional must not hide a following
  315. " command.
  316. "-------------------------------------------------------------------------------
  317. func T41_F()
  318. Xpath 'a'
  319. if 0 | throw 'never' | endif | Xpath 'b'
  320. Xpath 'c'
  321. endfunc
  322. func T41_G()
  323. Xpath 'd'
  324. while 0 | throw 'never' | endwhile | Xpath 'e'
  325. Xpath 'f'
  326. endfunc
  327. func T41_H()
  328. Xpath 'g'
  329. if 0 | try | throw 'never' | endtry | endif | Xpath 'h'
  330. Xpath 'i'
  331. endfunc
  332. func Test_throw_inactive_cond()
  333. XpathINIT
  334. try
  335. Xpath 'j'
  336. call T41_F()
  337. Xpath 'k'
  338. catch /.*/
  339. Xpath 'l'
  340. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  341. endtry
  342. try
  343. Xpath 'm'
  344. call T41_G()
  345. Xpath 'n'
  346. catch /.*/
  347. Xpath 'o'
  348. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  349. endtry
  350. try
  351. Xpath 'p'
  352. call T41_H()
  353. Xpath 'q'
  354. catch /.*/
  355. Xpath 'r'
  356. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  357. endtry
  358. call assert_equal('jabckmdefnpghiq', g:Xpath)
  359. endfunc
  360. "-------------------------------------------------------------------------------
  361. " Test 42: Catching number and string exceptions {{{1
  362. "
  363. " When a number is thrown, it is converted to a string exception.
  364. " Numbers and strings may be caught by specifying a regular exception
  365. " as argument to the :catch command.
  366. "-------------------------------------------------------------------------------
  367. func T42_F()
  368. try
  369. try
  370. Xpath 'a'
  371. throw 4711
  372. Xpath 'b'
  373. catch /4711/
  374. Xpath 'c'
  375. endtry
  376. try
  377. Xpath 'd'
  378. throw 4711
  379. Xpath 'e'
  380. catch /^4711$/
  381. Xpath 'f'
  382. endtry
  383. try
  384. Xpath 'g'
  385. throw 4711
  386. Xpath 'h'
  387. catch /\d/
  388. Xpath 'i'
  389. endtry
  390. try
  391. Xpath 'j'
  392. throw 4711
  393. Xpath 'k'
  394. catch /^\d\+$/
  395. Xpath 'l'
  396. endtry
  397. try
  398. Xpath 'm'
  399. throw "arrgh"
  400. Xpath 'n'
  401. catch /arrgh/
  402. Xpath 'o'
  403. endtry
  404. try
  405. Xpath 'p'
  406. throw "arrgh"
  407. Xpath 'q'
  408. catch /^arrgh$/
  409. Xpath 'r'
  410. endtry
  411. try
  412. Xpath 's'
  413. throw "arrgh"
  414. Xpath 't'
  415. catch /\l/
  416. Xpath 'u'
  417. endtry
  418. try
  419. Xpath 'v'
  420. throw "arrgh"
  421. Xpath 'w'
  422. catch /^\l\+$/
  423. Xpath 'x'
  424. endtry
  425. try
  426. try
  427. Xpath 'y'
  428. throw "ARRGH"
  429. Xpath 'z'
  430. catch /^arrgh$/
  431. Xpath 'A'
  432. endtry
  433. catch /^\carrgh$/
  434. Xpath 'B'
  435. endtry
  436. try
  437. Xpath 'C'
  438. throw ""
  439. Xpath 'D'
  440. catch /^$/
  441. Xpath 'E'
  442. endtry
  443. catch /.*/
  444. Xpath 'F'
  445. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  446. endtry
  447. endfunc
  448. func Test_catch_number_string()
  449. XpathINIT
  450. call T42_F()
  451. call assert_equal('acdfgijlmoprsuvxyBCE', g:Xpath)
  452. endfunc
  453. "-------------------------------------------------------------------------------
  454. " Test 43: Selecting the correct :catch clause {{{1
  455. "
  456. " When an exception is thrown and there are multiple :catch clauses,
  457. " the first matching one is taken.
  458. "-------------------------------------------------------------------------------
  459. func T43_F()
  460. let loops = 3
  461. while loops > 0
  462. try
  463. if loops == 3
  464. Xpath 'a' . loops
  465. throw "a"
  466. Xpath 'b' . loops
  467. elseif loops == 2
  468. Xpath 'c' . loops
  469. throw "ab"
  470. Xpath 'd' . loops
  471. elseif loops == 1
  472. Xpath 'e' . loops
  473. throw "abc"
  474. Xpath 'f' . loops
  475. endif
  476. catch /abc/
  477. Xpath 'g' . loops
  478. catch /ab/
  479. Xpath 'h' . loops
  480. catch /.*/
  481. Xpath 'i' . loops
  482. catch /a/
  483. Xpath 'j' . loops
  484. endtry
  485. let loops = loops - 1
  486. endwhile
  487. Xpath 'k'
  488. endfunc
  489. func Test_multi_catch()
  490. XpathINIT
  491. call T43_F()
  492. call assert_equal('a3i3c2h2e1g1k', g:Xpath)
  493. endfunc
  494. "-------------------------------------------------------------------------------
  495. " Test 44: Missing or empty :catch patterns {{{1
  496. "
  497. " A missing or empty :catch pattern means the same as /.*/, that is,
  498. " catches everything. To catch only empty exceptions, /^$/ must be
  499. " used. A :catch with missing, empty, or /.*/ argument also works
  500. " when followed by another command separated by a bar on the same
  501. " line. :catch patterns cannot be specified between ||. But other
  502. " pattern separators can be used instead of //.
  503. "-------------------------------------------------------------------------------
  504. func T44_F()
  505. try
  506. try
  507. Xpath 'a'
  508. throw ""
  509. catch /^$/
  510. Xpath 'b'
  511. endtry
  512. try
  513. Xpath 'c'
  514. throw ""
  515. catch /.*/
  516. Xpath 'd'
  517. endtry
  518. try
  519. Xpath 'e'
  520. throw ""
  521. catch //
  522. Xpath 'f'
  523. endtry
  524. try
  525. Xpath 'g'
  526. throw ""
  527. catch
  528. Xpath 'h'
  529. endtry
  530. try
  531. Xpath 'i'
  532. throw "oops"
  533. catch /^$/
  534. Xpath 'j'
  535. catch /.*/
  536. Xpath 'k'
  537. endtry
  538. try
  539. Xpath 'l'
  540. throw "arrgh"
  541. catch /^$/
  542. Xpath 'm'
  543. catch //
  544. Xpath 'n'
  545. endtry
  546. try
  547. Xpath 'o'
  548. throw "brrr"
  549. catch /^$/
  550. Xpath 'p'
  551. catch
  552. Xpath 'q'
  553. endtry
  554. try | Xpath 'r' | throw "x" | catch /.*/ | Xpath 's' | endtry
  555. try | Xpath 't' | throw "y" | catch // | Xpath 'u' | endtry
  556. while 1
  557. try
  558. let caught = 0
  559. let v:errmsg = ""
  560. " Extra try level: if ":catch" without arguments below raises
  561. " a syntax error because it misinterprets the "Xpath" as a pattern,
  562. " let it be caught by the ":catch /.*/" below.
  563. try
  564. try | Xpath 'v' | throw "z" | catch | Xpath 'w' | :
  565. endtry
  566. endtry
  567. catch /.*/
  568. let caught = 1
  569. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  570. finally
  571. if $VIMNOERRTHROW && v:errmsg != ""
  572. call assert_report(v:errmsg)
  573. endif
  574. if caught || $VIMNOERRTHROW && v:errmsg != ""
  575. Xpath 'x'
  576. endif
  577. break " discard error for $VIMNOERRTHROW
  578. endtry
  579. endwhile
  580. let cologne = 4711
  581. try
  582. try
  583. Xpath 'y'
  584. throw "throw cologne"
  585. " Next lines catches all and throws 4711:
  586. catch |throw cologne|
  587. Xpath 'z'
  588. endtry
  589. catch /4711/
  590. Xpath 'A'
  591. endtry
  592. try
  593. Xpath 'B'
  594. throw "plus"
  595. catch +plus+
  596. Xpath 'C'
  597. endtry
  598. Xpath 'D'
  599. catch /.*/
  600. Xpath 'E'
  601. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  602. endtry
  603. endfunc
  604. func Test_empty_catch()
  605. XpathINIT
  606. call T44_F()
  607. call assert_equal('abcdefghiklnoqrstuvwyABCD', g:Xpath)
  608. endfunc
  609. "-------------------------------------------------------------------------------
  610. " Test 45: Catching exceptions from nested :try blocks {{{1
  611. "
  612. " When :try blocks are nested, an exception is caught by the innermost
  613. " try conditional that has a matching :catch clause.
  614. "-------------------------------------------------------------------------------
  615. func T45_F()
  616. let loops = 3
  617. while loops > 0
  618. try
  619. try
  620. try
  621. try
  622. if loops == 3
  623. Xpath 'a' . loops
  624. throw "a"
  625. Xpath 'b' . loops
  626. elseif loops == 2
  627. Xpath 'c' . loops
  628. throw "ab"
  629. Xpath 'd' . loops
  630. elseif loops == 1
  631. Xpath 'e' . loops
  632. throw "abc"
  633. Xpath 'f' . loops
  634. endif
  635. catch /abc/
  636. Xpath 'g' . loops
  637. endtry
  638. catch /ab/
  639. Xpath 'h' . loops
  640. endtry
  641. catch /.*/
  642. Xpath 'i' . loops
  643. endtry
  644. catch /a/
  645. Xpath 'j' . loops
  646. endtry
  647. let loops = loops - 1
  648. endwhile
  649. Xpath 'k'
  650. endfunc
  651. func Test_catch_from_nested_try()
  652. XpathINIT
  653. call T45_F()
  654. call assert_equal('a3i3c2h2e1g1k', g:Xpath)
  655. endfunc
  656. "-------------------------------------------------------------------------------
  657. " Test 46: Executing :finally after a :throw in nested :try {{{1
  658. "
  659. " When an exception is thrown from within nested :try blocks, the
  660. " :finally clauses of the non-catching try conditionals should be
  661. " executed before the matching :catch of the next surrounding :try
  662. " gets the control. If this also has a :finally clause, it is
  663. " executed afterwards.
  664. "-------------------------------------------------------------------------------
  665. func T46_F()
  666. let sum = 0
  667. try
  668. Xpath 'a'
  669. try
  670. Xpath 'b'
  671. try
  672. Xpath 'c'
  673. try
  674. Xpath 'd'
  675. throw "ABC"
  676. Xpath 'e'
  677. catch /xyz/
  678. Xpath 'f'
  679. finally
  680. Xpath 'g'
  681. if sum != 0
  682. Xpath 'h'
  683. endif
  684. let sum = sum + 1
  685. endtry
  686. Xpath 'i'
  687. catch /123/
  688. Xpath 'j'
  689. catch /321/
  690. Xpath 'k'
  691. finally
  692. Xpath 'l'
  693. if sum != 1
  694. Xpath 'm'
  695. endif
  696. let sum = sum + 2
  697. endtry
  698. Xpath 'n'
  699. finally
  700. Xpath 'o'
  701. if sum != 3
  702. Xpath 'p'
  703. endif
  704. let sum = sum + 4
  705. endtry
  706. Xpath 'q'
  707. catch /ABC/
  708. Xpath 'r'
  709. if sum != 7
  710. Xpath 's'
  711. endif
  712. let sum = sum + 8
  713. finally
  714. Xpath 't'
  715. if sum != 15
  716. Xpath 'u'
  717. endif
  718. let sum = sum + 16
  719. endtry
  720. Xpath 'v'
  721. if sum != 31
  722. Xpath 'w'
  723. endif
  724. endfunc
  725. func Test_finally_after_throw()
  726. XpathINIT
  727. call T46_F()
  728. call assert_equal('abcdglortv', g:Xpath)
  729. endfunc
  730. "-------------------------------------------------------------------------------
  731. " Test 47: Throwing exceptions from a :catch clause {{{1
  732. "
  733. " When an exception is thrown from a :catch clause, it should not be
  734. " caught by a :catch of the same :try conditional. After executing
  735. " the :finally clause (if present), surrounding try conditionals
  736. " should be checked for a matching :catch.
  737. "-------------------------------------------------------------------------------
  738. func T47_F()
  739. Xpath 'a'
  740. try
  741. Xpath 'b'
  742. try
  743. Xpath 'c'
  744. try
  745. Xpath 'd'
  746. throw "x1"
  747. Xpath 'e'
  748. catch /x1/
  749. Xpath 'f'
  750. try
  751. Xpath 'g'
  752. throw "x2"
  753. Xpath 'h'
  754. catch /x1/
  755. Xpath 'i'
  756. catch /x2/
  757. Xpath 'j'
  758. try
  759. Xpath 'k'
  760. throw "x3"
  761. Xpath 'l'
  762. catch /x1/
  763. Xpath 'm'
  764. catch /x2/
  765. Xpath 'n'
  766. finally
  767. Xpath 'o'
  768. endtry
  769. Xpath 'p'
  770. catch /x3/
  771. Xpath 'q'
  772. endtry
  773. Xpath 'r'
  774. catch /x1/
  775. Xpath 's'
  776. catch /x2/
  777. Xpath 't'
  778. catch /x3/
  779. Xpath 'u'
  780. finally
  781. Xpath 'v'
  782. endtry
  783. Xpath 'w'
  784. catch /x1/
  785. Xpath 'x'
  786. catch /x2/
  787. Xpath 'y'
  788. catch /x3/
  789. Xpath 'z'
  790. endtry
  791. Xpath 'A'
  792. catch /.*/
  793. Xpath 'B'
  794. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  795. endtry
  796. Xpath 'C'
  797. endfunc
  798. func Test_throw_from_catch()
  799. XpathINIT
  800. call T47_F()
  801. call assert_equal('abcdfgjkovzAC', g:Xpath)
  802. endfunc
  803. "-------------------------------------------------------------------------------
  804. " Test 48: Throwing exceptions from a :finally clause {{{1
  805. "
  806. " When an exception is thrown from a :finally clause, it should not be
  807. " caught by a :catch of the same :try conditional. Surrounding try
  808. " conditionals should be checked for a matching :catch. A previously
  809. " thrown exception is discarded.
  810. "-------------------------------------------------------------------------------
  811. func T48_F()
  812. try
  813. try
  814. try
  815. Xpath 'a'
  816. catch /x1/
  817. Xpath 'b'
  818. finally
  819. Xpath 'c'
  820. throw "x1"
  821. Xpath 'd'
  822. endtry
  823. Xpath 'e'
  824. catch /x1/
  825. Xpath 'f'
  826. endtry
  827. Xpath 'g'
  828. try
  829. try
  830. Xpath 'h'
  831. throw "x2"
  832. Xpath 'i'
  833. catch /x2/
  834. Xpath 'j'
  835. catch /x3/
  836. Xpath 'k'
  837. finally
  838. Xpath 'l'
  839. throw "x3"
  840. Xpath 'm'
  841. endtry
  842. Xpath 'n'
  843. catch /x2/
  844. Xpath 'o'
  845. catch /x3/
  846. Xpath 'p'
  847. endtry
  848. Xpath 'q'
  849. try
  850. try
  851. try
  852. Xpath 'r'
  853. throw "x4"
  854. Xpath 's'
  855. catch /x5/
  856. Xpath 't'
  857. finally
  858. Xpath 'u'
  859. throw "x5" " discards 'x4'
  860. Xpath 'v'
  861. endtry
  862. Xpath 'w'
  863. catch /x4/
  864. Xpath 'x'
  865. finally
  866. Xpath 'y'
  867. endtry
  868. Xpath 'z'
  869. catch /x5/
  870. Xpath 'A'
  871. endtry
  872. Xpath 'B'
  873. catch /.*/
  874. Xpath 'C'
  875. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  876. endtry
  877. Xpath 'D'
  878. endfunc
  879. func Test_throw_from_finally()
  880. XpathINIT
  881. call T48_F()
  882. call assert_equal('acfghjlpqruyABD', g:Xpath)
  883. endfunc
  884. "-------------------------------------------------------------------------------
  885. " Test 51: Throwing exceptions across :execute and user commands {{{1
  886. "
  887. " A :throw command may be executed under an ":execute" or from
  888. " a user command.
  889. "-------------------------------------------------------------------------------
  890. func T51_F()
  891. command! -nargs=? THROW1 throw <args> | throw 1
  892. command! -nargs=? THROW2 try | throw <args> | endtry | throw 2
  893. command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry
  894. command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry
  895. try
  896. try
  897. try
  898. Xpath 'a'
  899. THROW1 "A"
  900. catch /A/
  901. Xpath 'b'
  902. endtry
  903. catch /1/
  904. Xpath 'c'
  905. endtry
  906. try
  907. try
  908. Xpath 'd'
  909. THROW2 "B"
  910. catch /B/
  911. Xpath 'e'
  912. endtry
  913. catch /2/
  914. Xpath 'f'
  915. endtry
  916. try
  917. try
  918. Xpath 'g'
  919. THROW3 "C"
  920. catch /C/
  921. Xpath 'h'
  922. endtry
  923. catch /3/
  924. Xpath 'i'
  925. endtry
  926. try
  927. try
  928. Xpath 'j'
  929. THROW4 "D"
  930. catch /D/
  931. Xpath 'k'
  932. endtry
  933. catch /4/
  934. Xpath 'l'
  935. endtry
  936. try
  937. try
  938. Xpath 'm'
  939. execute 'throw "E" | throw 5'
  940. catch /E/
  941. Xpath 'n'
  942. endtry
  943. catch /5/
  944. Xpath 'o'
  945. endtry
  946. try
  947. try
  948. Xpath 'p'
  949. execute 'try | throw "F" | endtry | throw 6'
  950. catch /F/
  951. Xpath 'q'
  952. endtry
  953. catch /6/
  954. Xpath 'r'
  955. endtry
  956. try
  957. try
  958. Xpath 's'
  959. execute'try | throw 7 | catch /7/ | throw "G" | endtry'
  960. catch /G/
  961. Xpath 't'
  962. endtry
  963. catch /7/
  964. Xpath 'u'
  965. endtry
  966. try
  967. try
  968. Xpath 'v'
  969. execute 'try | throw 8 | finally | throw "H" | endtry'
  970. catch /H/
  971. Xpath 'w'
  972. endtry
  973. catch /8/
  974. Xpath 'x'
  975. endtry
  976. catch /.*/
  977. Xpath 'y'
  978. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  979. endtry
  980. Xpath 'z'
  981. delcommand THROW1
  982. delcommand THROW2
  983. delcommand THROW3
  984. delcommand THROW4
  985. endfunc
  986. func Test_throw_across_commands()
  987. XpathINIT
  988. call T51_F()
  989. call assert_equal('abdeghjkmnpqstvwz', g:Xpath)
  990. endfunc
  991. "-------------------------------------------------------------------------------
  992. " Test 69: :throw across :if, :elseif, :while {{{1
  993. "
  994. " On an :if, :elseif, or :while command, an exception might be thrown
  995. " during evaluation of the expression to test. The exception can be
  996. " caught by the script.
  997. "-------------------------------------------------------------------------------
  998. func T69_throw(x)
  999. Xpath 'x'
  1000. throw a:x
  1001. endfunc
  1002. func Test_throw_ifelsewhile()
  1003. XpathINIT
  1004. try
  1005. try
  1006. Xpath 'a'
  1007. if 111 == T69_throw("if") + 111
  1008. Xpath 'b'
  1009. else
  1010. Xpath 'c'
  1011. endif
  1012. Xpath 'd'
  1013. catch /^if$/
  1014. Xpath 'e'
  1015. catch /.*/
  1016. Xpath 'f'
  1017. call assert_report("if: " . v:exception . " in " . v:throwpoint)
  1018. endtry
  1019. try
  1020. Xpath 'g'
  1021. if v:false
  1022. Xpath 'h'
  1023. elseif 222 == T69_throw("elseif") + 222
  1024. Xpath 'i'
  1025. else
  1026. Xpath 'j'
  1027. endif
  1028. Xpath 'k'
  1029. catch /^elseif$/
  1030. Xpath 'l'
  1031. catch /.*/
  1032. Xpath 'm'
  1033. call assert_report("elseif: " . v:exception . " in " . v:throwpoint)
  1034. endtry
  1035. try
  1036. Xpath 'n'
  1037. while 333 == T69_throw("while") + 333
  1038. Xpath 'o'
  1039. break
  1040. endwhile
  1041. Xpath 'p'
  1042. catch /^while$/
  1043. Xpath 'q'
  1044. catch /.*/
  1045. Xpath 'r'
  1046. call assert_report("while: " .. v:exception .. " in " .. v:throwpoint)
  1047. endtry
  1048. catch /^0$/ " default return value
  1049. Xpath 's'
  1050. call assert_report(v:throwpoint)
  1051. catch /.*/
  1052. call assert_report(v:exception .. " in " .. v:throwpoint)
  1053. Xpath 't'
  1054. endtry
  1055. call assert_equal('axegxlnxq', g:Xpath)
  1056. endfunc
  1057. "-------------------------------------------------------------------------------
  1058. " Test 70: :throw across :return or :throw {{{1
  1059. "
  1060. " On a :return or :throw command, an exception might be thrown during
  1061. " evaluation of the expression to return or throw, respectively. The
  1062. " exception can be caught by the script.
  1063. "-------------------------------------------------------------------------------
  1064. let T70_taken = ""
  1065. func T70_throw(x, n)
  1066. let g:T70_taken = g:T70_taken . "T" . a:n
  1067. throw a:x
  1068. endfunc
  1069. func T70_F(x, y, n)
  1070. let g:T70_taken = g:T70_taken . "F" . a:n
  1071. return a:x + T70_throw(a:y, a:n)
  1072. endfunc
  1073. func T70_G(x, y, n)
  1074. let g:T70_taken = g:T70_taken . "G" . a:n
  1075. throw a:x . T70_throw(a:y, a:n)
  1076. return a:x
  1077. endfunc
  1078. func Test_throwreturn()
  1079. XpathINIT
  1080. try
  1081. try
  1082. Xpath 'a'
  1083. call T70_F(4711, "return", 1)
  1084. Xpath 'b'
  1085. catch /^return$/
  1086. Xpath 'c'
  1087. catch /.*/
  1088. Xpath 'd'
  1089. call assert_report("return: " .. v:exception .. " in " .. v:throwpoint)
  1090. endtry
  1091. try
  1092. Xpath 'e'
  1093. let var = T70_F(4712, "return-var", 2)
  1094. Xpath 'f'
  1095. catch /^return-var$/
  1096. Xpath 'g'
  1097. catch /.*/
  1098. Xpath 'h'
  1099. call assert_report("return-var: " . v:exception . " in " . v:throwpoint)
  1100. finally
  1101. unlet! var
  1102. endtry
  1103. try
  1104. Xpath 'i'
  1105. throw "except1" . T70_throw("throw1", 3)
  1106. Xpath 'j'
  1107. catch /^except1/
  1108. Xpath 'k'
  1109. catch /^throw1$/
  1110. Xpath 'l'
  1111. catch /.*/
  1112. Xpath 'm'
  1113. call assert_report("throw1: " .. v:exception .. " in " .. v:throwpoint)
  1114. endtry
  1115. try
  1116. Xpath 'n'
  1117. call T70_G("except2", "throw2", 4)
  1118. Xpath 'o'
  1119. catch /^except2/
  1120. Xpath 'p'
  1121. catch /^throw2$/
  1122. Xpath 'q'
  1123. catch /.*/
  1124. Xpath 'r'
  1125. call assert_report("throw2: " .. v:exception .. " in " .. v:throwpoint)
  1126. endtry
  1127. try
  1128. Xpath 's'
  1129. let var = T70_G("except3", "throw3", 5)
  1130. Xpath 't'
  1131. catch /^except3/
  1132. Xpath 'u'
  1133. catch /^throw3$/
  1134. Xpath 'v'
  1135. catch /.*/
  1136. Xpath 'w'
  1137. call assert_report("throw3: " .. v:exception .. " in " .. v:throwpoint)
  1138. finally
  1139. unlet! var
  1140. endtry
  1141. call assert_equal('F1T1F2T2T3G4T4G5T5', g:T70_taken)
  1142. Xpath 'x'
  1143. catch /^0$/ " default return value
  1144. Xpath 'y'
  1145. call assert_report(v:throwpoint)
  1146. catch /.*/
  1147. Xpath 'z'
  1148. call assert_report('Caught' .. v:exception .. ' in ' .. v:throwpoint)
  1149. endtry
  1150. call assert_equal('acegilnqsvx', g:Xpath)
  1151. endfunc
  1152. "-------------------------------------------------------------------------------
  1153. " Test 71: :throw across :echo variants and :execute {{{1
  1154. "
  1155. " On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
  1156. " exception might be thrown during evaluation of the arguments to
  1157. " be displayed or executed as a command, respectively. Any following
  1158. " arguments are not evaluated, then. The exception can be caught by
  1159. " the script.
  1160. "-------------------------------------------------------------------------------
  1161. let T71_taken = ""
  1162. func T71_throw(x, n)
  1163. let g:T71_taken = g:T71_taken . "T" . a:n
  1164. throw a:x
  1165. endfunc
  1166. func T71_F(n)
  1167. let g:T71_taken = g:T71_taken . "F" . a:n
  1168. return "F" . a:n
  1169. endfunc
  1170. func Test_throw_echo()
  1171. XpathINIT
  1172. try
  1173. try
  1174. Xpath 'a'
  1175. echo 'echo ' . T71_throw("echo-except", 1) . T71_F(1)
  1176. Xpath 'b'
  1177. catch /^echo-except$/
  1178. Xpath 'c'
  1179. catch /.*/
  1180. Xpath 'd'
  1181. call assert_report("echo: " .. v:exception .. " in " .. v:throwpoint)
  1182. endtry
  1183. try
  1184. Xpath 'e'
  1185. echon "echon " . T71_throw("echon-except", 2) . T71_F(2)
  1186. Xpath 'f'
  1187. catch /^echon-except$/
  1188. Xpath 'g'
  1189. catch /.*/
  1190. Xpath 'h'
  1191. call assert_report('echon: ' . v:exception . ' in ' . v:throwpoint)
  1192. endtry
  1193. try
  1194. Xpath 'i'
  1195. echomsg "echomsg " . T71_throw("echomsg-except", 3) . T71_F(3)
  1196. Xpath 'j'
  1197. catch /^echomsg-except$/
  1198. Xpath 'k'
  1199. catch /.*/
  1200. Xpath 'l'
  1201. call assert_report('echomsg: ' . v:exception . ' in ' . v:throwpoint)
  1202. endtry
  1203. try
  1204. Xpath 'm'
  1205. echoerr "echoerr " . T71_throw("echoerr-except", 4) . T71_F(4)
  1206. Xpath 'n'
  1207. catch /^echoerr-except$/
  1208. Xpath 'o'
  1209. catch /Vim/
  1210. Xpath 'p'
  1211. catch /echoerr/
  1212. Xpath 'q'
  1213. catch /.*/
  1214. Xpath 'r'
  1215. call assert_report('echoerr: ' . v:exception . ' in ' . v:throwpoint)
  1216. endtry
  1217. try
  1218. Xpath 's'
  1219. execute "echo 'execute " . T71_throw("execute-except", 5) . T71_F(5) "'"
  1220. Xpath 't'
  1221. catch /^execute-except$/
  1222. Xpath 'u'
  1223. catch /.*/
  1224. Xpath 'v'
  1225. call assert_report('execute: ' . v:exception . ' in ' . v:throwpoint)
  1226. endtry
  1227. call assert_equal('T1T2T3T4T5', g:T71_taken)
  1228. Xpath 'w'
  1229. catch /^0$/ " default return value
  1230. Xpath 'x'
  1231. call assert_report(v:throwpoint)
  1232. catch /.*/
  1233. Xpath 'y'
  1234. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  1235. endtry
  1236. call assert_equal('acegikmosuw', g:Xpath)
  1237. endfunc
  1238. "-------------------------------------------------------------------------------
  1239. " Test 72: :throw across :let or :unlet {{{1
  1240. "
  1241. " On a :let command, an exception might be thrown during evaluation
  1242. " of the expression to assign. On an :let or :unlet command, the
  1243. " evaluation of the name of the variable to be assigned or list or
  1244. " deleted, respectively, may throw an exception. Any following
  1245. " arguments are not evaluated, then. The exception can be caught by
  1246. " the script.
  1247. "-------------------------------------------------------------------------------
  1248. let throwcount = 0
  1249. func T72_throw(x)
  1250. let g:throwcount = g:throwcount + 1
  1251. throw a:x
  1252. endfunc
  1253. let T72_addpath = ''
  1254. func T72_addpath(p)
  1255. let g:T72_addpath = g:T72_addpath . a:p
  1256. endfunc
  1257. func Test_throw_let()
  1258. XpathINIT
  1259. try
  1260. try
  1261. let $VAR = 'old_value'
  1262. Xpath 'a'
  1263. let $VAR = 'let(' . T72_throw('var') . ')'
  1264. Xpath 'b'
  1265. catch /^var$/
  1266. Xpath 'c'
  1267. finally
  1268. call assert_equal('old_value', $VAR)
  1269. endtry
  1270. try
  1271. let @a = 'old_value'
  1272. Xpath 'd'
  1273. let @a = 'let(' . T72_throw('reg') . ')'
  1274. Xpath 'e'
  1275. catch /^reg$/
  1276. try
  1277. Xpath 'f'
  1278. let @A = 'let(' . T72_throw('REG') . ')'
  1279. Xpath 'g'
  1280. catch /^REG$/
  1281. Xpath 'h'
  1282. endtry
  1283. finally
  1284. call assert_equal('old_value', @a)
  1285. call assert_equal('old_value', @A)
  1286. endtry
  1287. try
  1288. let saved_gpath = &g:path
  1289. let saved_lpath = &l:path
  1290. Xpath 'i'
  1291. let &path = 'let(' . T72_throw('opt') . ')'
  1292. Xpath 'j'
  1293. catch /^opt$/
  1294. try
  1295. Xpath 'k'
  1296. let &g:path = 'let(' . T72_throw('gopt') . ')'
  1297. Xpath 'l'
  1298. catch /^gopt$/
  1299. try
  1300. Xpath 'm'
  1301. let &l:path = 'let(' . T72_throw('lopt') . ')'
  1302. Xpath 'n'
  1303. catch /^lopt$/
  1304. Xpath 'o'
  1305. endtry
  1306. endtry
  1307. finally
  1308. call assert_equal(saved_gpath, &g:path)
  1309. call assert_equal(saved_lpath, &l:path)
  1310. let &g:path = saved_gpath
  1311. let &l:path = saved_lpath
  1312. endtry
  1313. unlet! var1 var2 var3
  1314. try
  1315. Xpath 'p'
  1316. let var1 = 'let(' . T72_throw('var1') . ')'
  1317. Xpath 'q'
  1318. catch /^var1$/
  1319. Xpath 'r'
  1320. finally
  1321. call assert_true(!exists('var1'))
  1322. endtry
  1323. try
  1324. let var2 = 'old_value'
  1325. Xpath 's'
  1326. let var2 = 'let(' . T72_throw('var2'). ')'
  1327. Xpath 't'
  1328. catch /^var2$/
  1329. Xpath 'u'
  1330. finally
  1331. call assert_equal('old_value', var2)
  1332. endtry
  1333. try
  1334. Xpath 'v'
  1335. let var{T72_throw('var3')} = 4711
  1336. Xpath 'w'
  1337. catch /^var3$/
  1338. Xpath 'x'
  1339. endtry
  1340. try
  1341. call T72_addpath('T1')
  1342. let var{T72_throw('var4')} var{T72_addpath('T2')} | call T72_addpath('T3')
  1343. call T72_addpath('T4')
  1344. catch /^var4$/
  1345. call T72_addpath('T5')
  1346. endtry
  1347. try
  1348. call T72_addpath('T6')
  1349. unlet var{T72_throw('var5')} var{T72_addpath('T7')}
  1350. \ | call T72_addpath('T8')
  1351. call T72_addpath('T9')
  1352. catch /^var5$/
  1353. call T72_addpath('T10')
  1354. endtry
  1355. call assert_equal('T1T5T6T10', g:T72_addpath)
  1356. call assert_equal(11, g:throwcount)
  1357. catch /.*/
  1358. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  1359. endtry
  1360. call assert_equal('acdfhikmoprsuvx', g:Xpath)
  1361. endfunc
  1362. "-------------------------------------------------------------------------------
  1363. " Test 73: :throw across :function, :delfunction {{{1
  1364. "
  1365. " The :function and :delfunction commands may cause an expression
  1366. " specified in braces to be evaluated. During evaluation, an
  1367. " exception might be thrown. The exception can be caught by the
  1368. " script.
  1369. "-------------------------------------------------------------------------------
  1370. let T73_taken = ''
  1371. func T73_throw(x, n)
  1372. let g:T73_taken = g:T73_taken . 'T' . a:n
  1373. throw a:x
  1374. endfunc
  1375. func T73_expr(x, n)
  1376. let g:T73_taken = g:T73_taken . 'E' . a:n
  1377. if a:n % 2 == 0
  1378. call T73_throw(a:x, a:n)
  1379. endif
  1380. return 2 - a:n % 2
  1381. endfunc
  1382. func Test_throw_func()
  1383. XpathINIT
  1384. try
  1385. try
  1386. " Define function.
  1387. Xpath 'a'
  1388. function! F0()
  1389. endfunction
  1390. Xpath 'b'
  1391. function! F{T73_expr('function-def-ok', 1)}()
  1392. endfunction
  1393. Xpath 'c'
  1394. function! F{T73_expr('function-def', 2)}()
  1395. endfunction
  1396. Xpath 'd'
  1397. catch /^function-def-ok$/
  1398. Xpath 'e'
  1399. catch /^function-def$/
  1400. Xpath 'f'
  1401. catch /.*/
  1402. call assert_report('def: ' . v:exception . ' in ' . v:throwpoint)
  1403. endtry
  1404. try
  1405. " List function.
  1406. Xpath 'g'
  1407. function F0
  1408. Xpath 'h'
  1409. function F{T73_expr('function-lst-ok', 3)}
  1410. Xpath 'i'
  1411. function F{T73_expr('function-lst', 4)}
  1412. Xpath 'j'
  1413. catch /^function-lst-ok$/
  1414. Xpath 'k'
  1415. catch /^function-lst$/
  1416. Xpath 'l'
  1417. catch /.*/
  1418. call assert_report('lst: ' . v:exception . ' in ' . v:throwpoint)
  1419. endtry
  1420. try
  1421. " Delete function
  1422. Xpath 'm'
  1423. delfunction F0
  1424. Xpath 'n'
  1425. delfunction F{T73_expr('function-del-ok', 5)}
  1426. Xpath 'o'
  1427. delfunction F{T73_expr('function-del', 6)}
  1428. Xpath 'p'
  1429. catch /^function-del-ok$/
  1430. Xpath 'q'
  1431. catch /^function-del$/
  1432. Xpath 'r'
  1433. catch /.*/
  1434. call assert_report('del: ' . v:exception . ' in ' . v:throwpoint)
  1435. endtry
  1436. call assert_equal('E1E2T2E3E4T4E5E6T6', g:T73_taken)
  1437. catch /.*/
  1438. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  1439. endtry
  1440. call assert_equal('abcfghilmnor', g:Xpath)
  1441. endfunc
  1442. "-------------------------------------------------------------------------------
  1443. " Test 74: :throw across builtin functions and commands {{{1
  1444. "
  1445. " Some functions like exists(), searchpair() take expression
  1446. " arguments, other functions or commands like substitute() or
  1447. " :substitute cause an expression (specified in the regular
  1448. " expression) to be evaluated. During evaluation an exception
  1449. " might be thrown. The exception can be caught by the script.
  1450. "-------------------------------------------------------------------------------
  1451. let T74_taken = ""
  1452. func T74_throw(x, n)
  1453. let g:T74_taken = g:T74_taken . "T" . a:n
  1454. throw a:x
  1455. endfunc
  1456. func T74_expr(x, n)
  1457. let g:T74_taken = g:T74_taken . "E" . a:n
  1458. call T74_throw(a:x . a:n, a:n)
  1459. return "EXPR"
  1460. endfunc
  1461. func T74_skip(x, n)
  1462. let g:T74_taken = g:T74_taken . "S" . a:n . "(" . line(".")
  1463. let theline = getline(".")
  1464. if theline =~ "skip"
  1465. let g:T74_taken = g:T74_taken . "s)"
  1466. return 1
  1467. elseif theline =~ "throw"
  1468. let g:T74_taken = g:T74_taken . "t)"
  1469. call T74_throw(a:x . a:n, a:n)
  1470. else
  1471. let g:T74_taken = g:T74_taken . ")"
  1472. return 0
  1473. endif
  1474. endfunc
  1475. func T74_subst(x, n)
  1476. let g:T74_taken = g:T74_taken . "U" . a:n . "(" . line(".")
  1477. let theline = getline(".")
  1478. if theline =~ "not" " T74_subst() should not be called for this line
  1479. let g:T74_taken = g:T74_taken . "n)"
  1480. call T74_throw(a:x . a:n, a:n)
  1481. elseif theline =~ "throw"
  1482. let g:T74_taken = g:T74_taken . "t)"
  1483. call T74_throw(a:x . a:n, a:n)
  1484. else
  1485. let g:T74_taken = g:T74_taken . ")"
  1486. return "replaced"
  1487. endif
  1488. endfunc
  1489. func Test_throw_builtin_func()
  1490. XpathINIT
  1491. try
  1492. try
  1493. Xpath 'a'
  1494. let result = exists('*{T74_expr("exists", 1)}')
  1495. Xpath 'b'
  1496. catch /^exists1$/
  1497. Xpath 'c'
  1498. try
  1499. let result = exists('{T74_expr("exists", 2)}')
  1500. Xpath 'd'
  1501. catch /^exists2$/
  1502. Xpath 'e'
  1503. catch /.*/
  1504. call assert_report('exists2: ' . v:exception . ' in ' . v:throwpoint)
  1505. endtry
  1506. catch /.*/
  1507. call assert_report('exists1: ' . v:exception . ' in ' . v:throwpoint)
  1508. endtry
  1509. try
  1510. let file = tempname()
  1511. exec "edit" file
  1512. call append(0, [
  1513. \ 'begin',
  1514. \ 'xx',
  1515. \ 'middle 3',
  1516. \ 'xx',
  1517. \ 'middle 5 skip',
  1518. \ 'xx',
  1519. \ 'middle 7 throw',
  1520. \ 'xx',
  1521. \ 'end'])
  1522. normal! gg
  1523. Xpath 'f'
  1524. let result = searchpair("begin", "middle", "end", '',
  1525. \ 'T74_skip("searchpair", 3)')
  1526. Xpath 'g'
  1527. let result = searchpair("begin", "middle", "end", '',
  1528. \ 'T74_skip("searchpair", 4)')
  1529. Xpath 'h'
  1530. let result = searchpair("begin", "middle", "end", '',
  1531. \ 'T74_skip("searchpair", 5)')
  1532. Xpath 'i'
  1533. catch /^searchpair[35]$/
  1534. Xpath 'j'
  1535. catch /^searchpair4$/
  1536. Xpath 'k'
  1537. catch /.*/
  1538. call assert_report('searchpair: ' . v:exception . ' in ' . v:throwpoint)
  1539. finally
  1540. bwipeout!
  1541. call delete(file)
  1542. endtry
  1543. try
  1544. let file = tempname()
  1545. exec "edit" file
  1546. call append(0, [
  1547. \ 'subst 1',
  1548. \ 'subst 2',
  1549. \ 'not',
  1550. \ 'subst 4',
  1551. \ 'subst throw',
  1552. \ 'subst 6'])
  1553. normal! gg
  1554. Xpath 'l'
  1555. 1,2substitute/subst/\=T74_subst("substitute", 6)/
  1556. try
  1557. Xpath 'm'
  1558. try
  1559. let v:errmsg = ""
  1560. 3substitute/subst/\=T74_subst("substitute", 7)/
  1561. finally
  1562. if v:errmsg != ""
  1563. " If exceptions are not thrown on errors, fake the error
  1564. " exception in order to get the same execution path.
  1565. throw "faked Vim(substitute)"
  1566. endif
  1567. endtry
  1568. catch /Vim(substitute)/ " Pattern not found ('e' flag missing)
  1569. Xpath 'n'
  1570. 3substitute/subst/\=T74_subst("substitute", 8)/e
  1571. Xpath 'o'
  1572. endtry
  1573. Xpath 'p'
  1574. 4,6substitute/subst/\=T74_subst("substitute", 9)/
  1575. Xpath 'q'
  1576. catch /^substitute[678]/
  1577. Xpath 'r'
  1578. catch /^substitute9/
  1579. Xpath 's'
  1580. finally
  1581. bwipeout!
  1582. call delete(file)
  1583. endtry
  1584. try
  1585. Xpath 't'
  1586. let var = substitute("sub", "sub", '\=T74_throw("substitute()y", 10)', '')
  1587. Xpath 'u'
  1588. catch /substitute()y/
  1589. Xpath 'v'
  1590. catch /.*/
  1591. call assert_report('substitute()y: ' . v:exception . ' in '
  1592. \ . v:throwpoint)
  1593. endtry
  1594. try
  1595. Xpath 'w'
  1596. let var = substitute("not", "sub", '\=T74_throw("substitute()n", 11)', '')
  1597. Xpath 'x'
  1598. catch /substitute()n/
  1599. Xpath 'y'
  1600. catch /.*/
  1601. call assert_report('substitute()n: ' . v:exception . ' in '
  1602. \ . v:throwpoint)
  1603. endtry
  1604. call assert_equal('E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10',
  1605. \ g:T74_taken)
  1606. catch /.*/
  1607. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  1608. endtry
  1609. call assert_equal('acefgklmnopstvwx', g:Xpath)
  1610. endfunc
  1611. "-------------------------------------------------------------------------------
  1612. " Test 75: Errors in builtin functions. {{{1
  1613. "
  1614. " On an error in a builtin function called inside a :try/:endtry
  1615. " region, the evaluation of the expression calling that function and
  1616. " the command containing that expression are abandoned. The error can
  1617. " be caught as an exception.
  1618. "
  1619. " A simple :call of the builtin function is a trivial case. If the
  1620. " builtin function is called in the argument list of another function,
  1621. " no further arguments are evaluated, and the other function is not
  1622. " executed. If the builtin function is called from the argument of
  1623. " a :return command, the :return command is not executed. If the
  1624. " builtin function is called from the argument of a :throw command,
  1625. " the :throw command is not executed. The evaluation of the
  1626. " expression calling the builtin function is abandoned.
  1627. "-------------------------------------------------------------------------------
  1628. func T75_F1(arg1)
  1629. Xpath 'a'
  1630. endfunc
  1631. func T75_F2(arg1, arg2)
  1632. Xpath 'b'
  1633. endfunc
  1634. func T75_G()
  1635. Xpath 'c'
  1636. endfunc
  1637. func T75_H()
  1638. Xpath 'd'
  1639. endfunc
  1640. func T75_R()
  1641. while 1
  1642. try
  1643. let caught = 0
  1644. let v:errmsg = ""
  1645. Xpath 'e'
  1646. return append(1, "s")
  1647. catch /E21/
  1648. let caught = 1
  1649. catch /.*/
  1650. Xpath 'f'
  1651. finally
  1652. Xpath 'g'
  1653. if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
  1654. Xpath 'h'
  1655. endif
  1656. break " discard error for $VIMNOERRTHROW
  1657. endtry
  1658. endwhile
  1659. Xpath 'i'
  1660. endfunc
  1661. func Test_builtin_func_error()
  1662. XpathINIT
  1663. try
  1664. set noma " let append() fail with "E21"
  1665. while 1
  1666. try
  1667. let caught = 0
  1668. let v:errmsg = ""
  1669. Xpath 'j'
  1670. call append(1, "s")
  1671. catch /E21/
  1672. let caught = 1
  1673. catch /.*/
  1674. Xpath 'k'
  1675. finally
  1676. Xpath 'l'
  1677. if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
  1678. Xpath 'm'
  1679. endif
  1680. break " discard error for $VIMNOERRTHROW
  1681. endtry
  1682. endwhile
  1683. while 1
  1684. try
  1685. let caught = 0
  1686. let v:errmsg = ""
  1687. Xpath 'n'
  1688. call T75_F1('x' . append(1, "s"))
  1689. catch /E21/
  1690. let caught = 1
  1691. catch /.*/
  1692. Xpath 'o'
  1693. finally
  1694. Xpath 'p'
  1695. if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
  1696. Xpath 'q'
  1697. endif
  1698. break " discard error for $VIMNOERRTHROW
  1699. endtry
  1700. endwhile
  1701. while 1
  1702. try
  1703. let caught = 0
  1704. let v:errmsg = ""
  1705. Xpath 'r'
  1706. call T75_F2('x' . append(1, "s"), T75_G())
  1707. catch /E21/
  1708. let caught = 1
  1709. catch /.*/
  1710. Xpath 's'
  1711. finally
  1712. Xpath 't'
  1713. if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
  1714. Xpath 'u'
  1715. endif
  1716. break " discard error for $VIMNOERRTHROW
  1717. endtry
  1718. endwhile
  1719. call T75_R()
  1720. while 1
  1721. try
  1722. let caught = 0
  1723. let v:errmsg = ""
  1724. Xpath 'v'
  1725. throw "T" . append(1, "s")
  1726. catch /E21/
  1727. let caught = 1
  1728. catch /^T.*/
  1729. Xpath 'w'
  1730. catch /.*/
  1731. Xpath 'x'
  1732. finally
  1733. Xpath 'y'
  1734. if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
  1735. Xpath 'z'
  1736. endif
  1737. break " discard error for $VIMNOERRTHROW
  1738. endtry
  1739. endwhile
  1740. while 1
  1741. try
  1742. let caught = 0
  1743. let v:errmsg = ""
  1744. Xpath 'A'
  1745. let x = "a"
  1746. let x = x . "b" . append(1, "s") . T75_H()
  1747. catch /E21/
  1748. let caught = 1
  1749. catch /.*/
  1750. Xpath 'B'
  1751. finally
  1752. Xpath 'C'
  1753. if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
  1754. Xpath 'D'
  1755. endif
  1756. call assert_equal('a', x)
  1757. break " discard error for $VIMNOERRTHROW
  1758. endtry
  1759. endwhile
  1760. catch /.*/
  1761. call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
  1762. finally
  1763. set ma&
  1764. endtry
  1765. call assert_equal('jlmnpqrtueghivyzACD', g:Xpath)
  1766. endfunc
  1767. func Test_reload_in_try_catch()
  1768. call writefile(['x'], 'Xreload')
  1769. set autoread
  1770. edit Xreload
  1771. tabnew
  1772. call writefile(['xx'], 'Xreload')
  1773. augroup ReLoad
  1774. au FileReadPost Xreload let x = doesnotexist
  1775. au BufReadPost Xreload let x = doesnotexist
  1776. augroup END
  1777. try
  1778. edit Xreload
  1779. catch
  1780. endtry
  1781. tabnew
  1782. tabclose
  1783. tabclose
  1784. autocmd! ReLoad
  1785. set noautoread
  1786. bwipe! Xreload
  1787. call delete('Xreload')
  1788. endfunc
  1789. " Test for errors with :catch, :throw, :finally {{{1
  1790. func Test_try_catch_errors()
  1791. call assert_fails('throw |', 'E471:')
  1792. call assert_fails("throw \n ", 'E471:')
  1793. call assert_fails('catch abc', 'E654:')
  1794. call assert_fails('try | let i = 1| finally | catch | endtry', 'E604:')
  1795. call assert_fails('finally', 'E606:')
  1796. call assert_fails('try | finally | finally | endtry', 'E607:')
  1797. call assert_fails('try | for i in range(5) | endif | endtry', 'E580:')
  1798. call assert_fails('try | while v:true | endtry', 'E170:')
  1799. call assert_fails('try | if v:true | endtry', 'E171:')
  1800. " this was using a negative index in cstack[]
  1801. let lines =<< trim END
  1802. try
  1803. for
  1804. if
  1805. endwhile
  1806. if
  1807. finally
  1808. END
  1809. call CheckScriptFailure(lines, 'E690:')
  1810. let lines =<< trim END
  1811. try
  1812. for
  1813. if
  1814. endwhile
  1815. if
  1816. endtry
  1817. END
  1818. call CheckScriptFailure(lines, 'E690:')
  1819. endfunc
  1820. " Test for verbose messages with :try :catch, and :finally {{{1
  1821. func Test_try_catch_verbose()
  1822. " This test works only when the language is English
  1823. CheckEnglish
  1824. set verbose=14
  1825. " Test for verbose messages displayed when an exception is caught
  1826. redir => msg
  1827. try
  1828. echo i
  1829. catch /E121:/
  1830. finally
  1831. endtry
  1832. redir END
  1833. let expected = [
  1834. \ 'Exception thrown: Vim(echo):E121: Undefined variable: i', '',
  1835. \ 'Exception caught: Vim(echo):E121: Undefined variable: i', '',
  1836. \ 'Exception finished: Vim(echo):E121: Undefined variable: i']
  1837. call assert_equal(expected, split(msg, "\n"))
  1838. " Test for verbose messages displayed when an exception is discarded
  1839. redir => msg
  1840. try
  1841. try
  1842. throw 'abc'
  1843. finally
  1844. throw 'xyz'
  1845. endtry
  1846. catch
  1847. endtry
  1848. redir END
  1849. let expected = [
  1850. \ 'Exception thrown: abc', '',
  1851. \ 'Exception made pending: abc', '',
  1852. \ 'Exception thrown: xyz', '',
  1853. \ 'Exception discarded: abc', '',
  1854. \ 'Exception caught: xyz', '',
  1855. \ 'Exception finished: xyz']
  1856. call assert_equal(expected, split(msg, "\n"))
  1857. " Test for messages displayed when :throw is resumed after :finally
  1858. redir => msg
  1859. try
  1860. try
  1861. throw 'abc'
  1862. finally
  1863. endtry
  1864. catch
  1865. endtry
  1866. redir END
  1867. let expected = [
  1868. \ 'Exception thrown: abc', '',
  1869. \ 'Exception made pending: abc', '',
  1870. \ 'Exception resumed: abc', '',
  1871. \ 'Exception caught: abc', '',
  1872. \ 'Exception finished: abc']
  1873. call assert_equal(expected, split(msg, "\n"))
  1874. " Test for messages displayed when :break is resumed after :finally
  1875. redir => msg
  1876. for i in range(1)
  1877. try
  1878. break
  1879. finally
  1880. endtry
  1881. endfor
  1882. redir END
  1883. let expected = [':break made pending', '', ':break resumed']
  1884. call assert_equal(expected, split(msg, "\n"))
  1885. " Test for messages displayed when :continue is resumed after :finally
  1886. redir => msg
  1887. for i in range(1)
  1888. try
  1889. continue
  1890. finally
  1891. endtry
  1892. endfor
  1893. redir END
  1894. let expected = [':continue made pending', '', ':continue resumed']
  1895. call assert_equal(expected, split(msg, "\n"))
  1896. " Test for messages displayed when :return is resumed after :finally
  1897. func Xtest()
  1898. try
  1899. return 'vim'
  1900. finally
  1901. endtry
  1902. endfunc
  1903. redir => msg
  1904. call Xtest()
  1905. redir END
  1906. let expected = [
  1907. \ 'calling Xtest()', '',
  1908. \ ':return vim made pending', '',
  1909. \ ':return vim resumed', '',
  1910. \ 'Xtest returning ''vim''', '',
  1911. \ 'continuing in Test_try_catch_verbose']
  1912. call assert_equal(expected, split(msg, "\n"))
  1913. delfunc Xtest
  1914. " Test for messages displayed when :finish is resumed after :finally
  1915. call writefile(['try', 'finish', 'finally', 'endtry'], 'Xscript')
  1916. redir => msg
  1917. source Xscript
  1918. redir END
  1919. let expected = [
  1920. \ ':finish made pending', '',
  1921. \ ':finish resumed', '',
  1922. \ 'finished sourcing Xscript',
  1923. \ 'continuing in Test_try_catch_verbose']
  1924. call assert_equal(expected, split(msg, "\n")[1:])
  1925. call delete('Xscript')
  1926. " Test for messages displayed when a pending :continue is discarded by an
  1927. " exception in a finally handler
  1928. redir => msg
  1929. try
  1930. for i in range(1)
  1931. try
  1932. continue
  1933. finally
  1934. throw 'abc'
  1935. endtry
  1936. endfor
  1937. catch
  1938. endtry
  1939. redir END
  1940. let expected = [
  1941. \ ':continue made pending', '',
  1942. \ 'Exception thrown: abc', '',
  1943. \ ':continue discarded', '',
  1944. \ 'Exception caught: abc', '',
  1945. \ 'Exception finished: abc']
  1946. call assert_equal(expected, split(msg, "\n"))
  1947. set verbose&
  1948. endfunc
  1949. " Test for throwing an exception from a BufEnter autocmd {{{1
  1950. func Test_BufEnter_exception()
  1951. augroup bufenter_exception
  1952. au!
  1953. autocmd BufEnter Xfile1 throw 'abc'
  1954. augroup END
  1955. let caught_abc = 0
  1956. try
  1957. sp Xfile1
  1958. catch /^abc/
  1959. let caught_abc = 1
  1960. endtry
  1961. call assert_equal(1, caught_abc)
  1962. call assert_equal(1, winnr('$'))
  1963. augroup bufenter_exception
  1964. au!
  1965. augroup END
  1966. augroup! bufenter_exception
  1967. %bwipe!
  1968. " Test for recursively throwing exceptions in autocmds
  1969. augroup bufenter_exception
  1970. au!
  1971. autocmd BufEnter Xfile1 throw 'bufenter'
  1972. autocmd BufLeave Xfile1 throw 'bufleave'
  1973. augroup END
  1974. let ex_count = 0
  1975. try
  1976. try
  1977. sp Xfile1
  1978. catch /^bufenter/
  1979. let ex_count += 1
  1980. endtry
  1981. catch /^bufleave/
  1982. let ex_count += 10
  1983. endtry
  1984. call assert_equal(10, ex_count)
  1985. call assert_equal(2, winnr('$'))
  1986. augroup bufenter_exception
  1987. au!
  1988. augroup END
  1989. augroup! bufenter_exception
  1990. %bwipe!
  1991. endfunc
  1992. " Test for using try/catch when lines are joined by "|" or "\n" {{{1
  1993. func Test_try_catch_nextcmd()
  1994. func Throw()
  1995. throw "Failure"
  1996. endfunc
  1997. let lines =<< trim END
  1998. try
  1999. let s:x = Throw()
  2000. catch
  2001. let g:caught = 1
  2002. endtry
  2003. END
  2004. let g:caught = 0
  2005. call execute(lines)
  2006. call assert_equal(1, g:caught)
  2007. let g:caught = 0
  2008. call execute(join(lines, '|'))
  2009. call assert_equal(1, g:caught)
  2010. let g:caught = 0
  2011. call execute(join(lines, "\n"))
  2012. call assert_equal(1, g:caught)
  2013. unlet g:caught
  2014. delfunc Throw
  2015. endfunc
  2016. " Test for using try/catch in a user command with a failing expression {{{1
  2017. func Test_user_command_try_catch()
  2018. let lines =<< trim END
  2019. function s:throw() abort
  2020. throw 'error'
  2021. endfunction
  2022. command! Execute
  2023. \ try
  2024. \ | let s:x = s:throw()
  2025. \ | catch
  2026. \ | let g:caught = 'caught'
  2027. \ | endtry
  2028. let g:caught = 'no'
  2029. Execute
  2030. call assert_equal('caught', g:caught)
  2031. END
  2032. call writefile(lines, 'XtestTryCatch')
  2033. source XtestTryCatch
  2034. call delete('XtestTryCatch')
  2035. unlet g:caught
  2036. endfunc
  2037. " Test for using throw in a called function with following error {{{1
  2038. func Test_user_command_throw_in_function_call()
  2039. let lines =<< trim END
  2040. function s:get_dict() abort
  2041. throw 'my_error'
  2042. endfunction
  2043. try
  2044. call s:get_dict().foo()
  2045. catch /my_error/
  2046. let caught = 'yes'
  2047. catch
  2048. let caught = v:exception
  2049. endtry
  2050. call assert_equal('yes', caught)
  2051. END
  2052. call writefile(lines, 'XtestThrow')
  2053. source XtestThrow
  2054. call delete('XtestThrow')
  2055. unlet g:caught
  2056. endfunc
  2057. " Test that after reporting an uncaught exception there is no error for a
  2058. " missing :endif
  2059. func Test_after_exception_no_endif_error()
  2060. function Throw()
  2061. throw "Failure"
  2062. endfunction
  2063. function Foo()
  2064. if 1
  2065. call Throw()
  2066. endif
  2067. endfunction
  2068. call assert_fails('call Foo()', ['E605:', 'E605:'])
  2069. delfunc Throw
  2070. delfunc Foo
  2071. endfunc
  2072. " Test for using throw in a called function with following endtry {{{1
  2073. func Test_user_command_function_call_with_endtry()
  2074. let lines =<< trim END
  2075. funct s:throw(msg) abort
  2076. throw a:msg
  2077. endfunc
  2078. func s:main() abort
  2079. try
  2080. try
  2081. throw 'err1'
  2082. catch
  2083. call s:throw('err2') | endtry
  2084. catch
  2085. let s:caught = 'yes'
  2086. endtry
  2087. endfunc
  2088. call s:main()
  2089. call assert_equal('yes', s:caught)
  2090. END
  2091. call writefile(lines, 'XtestThrow')
  2092. source XtestThrow
  2093. call delete('XtestThrow')
  2094. endfunc
  2095. func ThisWillFail()
  2096. endfunc
  2097. " This was crashing prior to the fix in 8.2.3478.
  2098. func Test_error_in_catch_and_finally()
  2099. let lines =<< trim END
  2100. try
  2101. echo x
  2102. catch
  2103. for l in []
  2104. finally
  2105. END
  2106. call writefile(lines, 'XtestCatchAndFinally')
  2107. try
  2108. source XtestCatchAndFinally
  2109. catch /E600:/
  2110. endtry
  2111. call delete('XtestCatchAndFinally')
  2112. endfunc
  2113. " This was causing an illegal memory access
  2114. func Test_leave_block_in_endtry_not_called()
  2115. let lines =<< trim END
  2116. " vim9script
  2117. " try #
  2118. try "
  2119. for x in []
  2120. if
  2121. endwhile
  2122. if
  2123. endtry
  2124. END
  2125. call writefile(lines, 'XtestEndtry')
  2126. try
  2127. source XtestEndtry
  2128. catch /E171:/
  2129. endtry
  2130. call delete('XtestEndtry')
  2131. endfunc
  2132. " Modeline {{{1
  2133. " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker