** Implement on user defined Errs to list available values in the stack trace.
** This gives the user helpful context when a value could not be found.
** Typical usage would be:
**
** pre>
** syntax: fantom
**
** const class MyNotFoundErr : Err, NotFoundErr {
** override const Str?[] availableValues
**
** new make(Str msg, Obj?[] availableValues, Err? cause := null) : super(msg, cause) {
** this.availableValues = availableValues.map { it?.toStr }.sort
** }
**
** override Str toStr() {
** NotFoundErr.super.toStr
** }
** }
** <pre
**
** Which when thrown with:
**
** throw MyNotFoundErr("Could not find a sausage.", ["steak", "hot dog", "burger"])
**
** Gives a helpful stack trace of:
**
** pre>
** MyNotFoundErr: Could not find a sausage.
**
** Available values:
** burger
** hot dog
** steak
**
** Stack Trace:
** afTest::Wotever.main (Wotever.fan:69)
** java.lang.reflect.Method.invoke (Method.java:597)
** fan.sys.Method.invoke (Method.java:559)
** fan.sys.Method$MethodFunc.callOn (Method.java:230)
** fanx.tools.Fan.callMain (Fan.java:175)
** fanx.tools.Fan.executeType (Fan.java:140)
** ...
** <pre
**
** Note that [BedSheet]`http://www.fantomfactory.org/pods/afBedSheet` gives special treatment to
** 'NotFoundErrs' on its standard Err 500 page and lists the available values in its own section.
@Js
const mixin NotFoundErr {
** The standard 'Err' msg.
abstract Str msg()
** A list of values the user could have used chosen.
abstract Str?[] availableValues()
** The msg that prefixes the list of values.
**
** Defaults to '"Available values:"'. Override to change it.
virtual Str valueMsg() {
"Available values:"
}
** Pre-pends the list of available values to the stack trace.
override Str toStr() {
buf := StrBuf()
buf.add("${typeof.qname}: ${msg}\n")
buf.add("\n${valueMsg}\n")
availableValues.each { buf.add(" $it\n")}
buf.add("\nStack Trace:")
return buf.toStr
}
}