Unbundling ERROR! FORM-ing

Historically, Redbol has put a lot of information into the FORM-ing of ERROR!s.

To give an example, this Red program:

Red []

boom: func [] [do make error! "boom"]
e: try [boom]
print ["Your error was:" form e]

Produces the following output:

Your error was: *** User Error: boom
*** Where: do
*** Near : do make error! "boom"
*** Stack: boom

That's awfully prescriptive, in terms of including stars and such. (Ren-C includes optional File and Line components, so there's more information).

I ran into problems with this approach specifically because I want some errors to show up as "PANIC" with others showing as "ERROR" in the console... based on whether it's an exception or a definitional ERROR! as a direct evaluation product.

What If FORM is Just the Message Part?

The only non-trivial behavior of FORM with errors is the knowledge of the arg1: arg2: convention and splicing those into the message template.

The rest of it is just picking fields out if they are there, and molding them.

So what if you FORM an error and that gives you the message, with the rest done by some usermode function?

It seems to me the knowledge of whether you want to use stars or things like that is kind of a console decision. If you build a Rebol without a console then maybe you'd just fall back on MOLD by default?

Concept: Lightweight Report of Definitional ERROR!

It's not so important to say where a definitional error occurred, because it's the result of the expression. So it can be light:

>> 1 / 0
** Error: attempt to divide by zero
** Id: zero-divide

>> try 1 / 0
== \~null~\  ; antiform (keyword!)

>> disarm 1 / 0
== &[warning! [
    type: 'math
    id: 'zero-divide
    message: "attempt to divide by zero"
    near: '[... 1 / 0 **]
    where: '[divide {disarm} eval catch* enrecover eval-free {match} recover console]
    file: ~null~
    line: ~null~
]]

(The usermode console should erase its presence in the callstack, TBD.)

More Information on a PANIC

Kind of by definition you don't know where a PANIC happened, so you want more information in that case:

>> (1 / 0) + 100
** PANIC: attempt to divide by zero
** Id: zero-divide
** Where: [divide eval catch* enrecover eval-free {match} recover console]
** Near: [1 / 0 **]

PRINT-ERROR and PRINT-PANIC are Distinct In Console

You can customize this if you want.

The only thing FORM gives you on a WARNING! is it puts together the error string from the field substitutions...the rest is just code in those functions.