Consider the following code:
proc f(callback: proc()) {.raises: [].} =
callback()
proc g() {.raises: [ValueError].} =
raise newException(ValueError, "")
f(g)
This incorrect, as f does raise an exception, but above code compiles because whether f invokes g cannot be determined at the compile-time. We cannot mark f as {.raises: [].}, nor can we mark it as raising something, because we don't know what kind of exceptions the callback will raise.
My suggestion is to interduce a concept named SomeException
type SomeException = concept x
x of Exception
Then we can mark f as {.raises: [SomeException].} to mean that "this proc can raise an exception This is what effectsOf is for:
proc f(callback: proc()) {.effectsOf:callback.} =
callback()
proc g() {.raises: [ValueError].} =
raise newException(ValueError, "")
proc h(){.raises:[].} =
f(g)
does not compile because f(g) raises