If you haven't been using FAIL, you should! I've pointed out in the past you can just say case [... fail] and that's enough to get a failure and point to that location. But it now lets you just point at any arbitrary value via a quoted word and it will complain about that word and its value:
>> foo: 10
>> fail 'foo
** Error: foo is invalid: 10
** Where: fail console
** Near: [fail 'foo ~~]
It works for tuples too:
>> obj: make object! [field: <I've been a bad, bad field...>]
>> fail 'obj.field
** Error: obj.field is invalid: <I've been a bad, bad field...>
** Where: fail console
** Near: [fail 'obj.field ~~]
So this should be your lazy go-to for reporting errors, you get more information and type less than using PRINTs or longer-winded messages.
But the real strength is implicating callsites, vs FAILs
If you don't provide a place to blame, the only thing the evaluator knows is the whole stack and the place the failure was.
my-api: func [x y z] [
if true [
if y < 100 [
fail "Who's failing? one of those IFs? Or MY-API?"
]
]
]
>> my-api 1 2 3
** Error: Who's failing? one of those IFs? Or MY-API?
** Where: fail if if my-api console
** Near: [
fail "Who's failing? one of those IFs? Or MY-API?" ~...
That's not a terribly informative error message, but the evaluator doesn't know any more unless you tell it.
This is a job for FAIL/BLAME! Just pass it a WORD! from the frame you wanted to complain about.
my-api: func [x y z] [
if true [
if y < 100 [
fail/blame ["Value must be >= 100, not" y] 'y
]
]
]
>> my-api 1 2 3
** Error: Value must be >= 100, not 2
** Where: my-api console
** Near: [... 1 2 3 ~~]
Now the IFs are gone from the reporting stack, and you're indicating the callsite but not the FAIL itself. (Ideally the error message would point to the exact block position where the parameter you are complaining about originated from. But that information is not preserved at the moment. In the future it might be kept...maybe in a special slot that would go unused otherwise in 64-bit builds. So the error report would improve!)
Again, you could be lazy and just say fail 'y
and get a fair amount of information. In this case a bit of better information than in the custom message provided--in terms of the right name of the bad parameter!
This isn't arcane C magic, it's usermode Rebol!
You can read and help improve FAIL any day you feel like it! Please do!