exercism / nim-test-runner

GNU Affero General Public License v3.0
2 stars 3 forks source link

improve error message for call depth limit #85

Open ee7 opened 3 years ago

ee7 commented 3 years ago

Reported by @axtens in Slack:

Crashed the nim runner with the following code in Reverse String

import sequtils, strutils

var seq_reverse: proc( str:  seq[char]): seq[char]

seq_reverse = proc( str:  seq[char]): seq[char] = 
 if str.len == 1:
   str[0..0]
 else:
   var slice = str
   slice.delete(0,0)
   #let revved = reverse(slice)
   concat(seq_reverse(slice), str[0..0])

proc reverse*(str: string): string =
 cast[string](seq_reverse(toSeq(str)))

echo reverse("dog")

Worked fine in Nim Playground, see https://play.nim-lang.org/#ix=3s0y


The error:

parsejson.nim(522)       raiseParseErr
Error: unhandled exception: /mnt/exercism-iteration/results.json(1, 0) Error: { expected [JsonParsingError]

The website produces the message:

An error occurred while running your tests. This might mean that there was an issue in our infrastructure, or it might mean that you have something in your code that's causing our systems to break.

Please check your code, and if nothing seems to be wrong, try running the tests again.

ee7 commented 3 years ago

Minimizing the code slightly:

import std/sequtils

var seqReverse: proc(str: seq[char]): seq[char]

seqReverse = proc(str: seq[char]): seq[char] =
  if str.len == 1:
    str[0..0]
  else:
    var slice = str
    slice.delete(0, 0)
    concat(seqReverse(slice), str[0..0])

proc reverse*(str: string): string =
  for c in seqReverse(toSeq(str)):
    result.add c

The problem is that the empty string test case causes an infinite recursion. So when the tests call

check reverse("") == ""

we get

/usr/lib/nim/system/assign.nim(179) genericSeqAssign
/usr/lib/nim/system/assign.nim(143) genericAssign
/usr/lib/nim/system/assign.nim(89) genericAssignAux
/usr/lib/nim/system/mmdisp.nim(104) nimNewSeqOfCap
/usr/lib/nim/system/gc.nim(482) newObjNoInit
/usr/lib/nim/system/alloc.nim(753) rawAlloc
/usr/lib/nim/system/osalloc.nim roundup
Error: call depth limit reached in a debug build (2000 function calls). You can change it with -d:nimCallDepthLimit=<int> but really try to avoid deep recursions instead.

A minimal reproducible example:

proc reverse*(s: string): string =
  reverse(s)

echo reverse("foo")
ynfle commented 3 years ago

I'm having a hard time debugging because no stack trace was printing as is the expected behaviour for -d:release. I'm guessing that the issue is when there is a runtime exception, results.json file isn't written properly, and therefore when parsing the results.json file to reinsert the stdout there is a parsing error and the program just exits.

@iHiD is there a way to get the /mnt/exercism-iteration/results.json from that run? I also just tried the same kind of thing and got the same error.

I will try and test locally

ee7 commented 3 years ago

The results.json is written without any contents. That fits the error message:

Error: unhandled exception: /mnt/exercism-iteration/results.json(1, 0) Error: { expected [JsonParsingError]

Opened a draft https://github.com/exercism/nim-test-runner/pull/87, but I'm away for a bit.