func NewErrorDetailed(err ErrNo, msg string) error {
    if len(msg) == 0 {
        msg = errorStr[err]
    }
	return &errorDef{
        err: err,
        message: msg, 
    }
}
NewErrorDetailed creates a new error with the given error no and message
package rbt
import (
    "fmt"
)
type ErrNo uintptr
const (
    ErrNoArgumentNil ErrNo = iota + 1
    ErrNoArgumentNilWithName
    ErrNoEnumeratorModified
    ErrNoIteratorAlreadyRunning
    ErrNoIteratorClosed
    ErrNoIteratorUninitialized
)
var (
    ErrArgumentNil = NewError(ErrNoArgumentNil) 
    ErrEnumeratorModified = NewError(ErrNoEnumeratorModified)
    ErrIteratorAlreadyRunning = NewError(ErrNoIteratorAlreadyRunning)
    ErrIteratorClosed = NewError(ErrNoIteratorClosed)
    ErrIteratorUninitialized = NewError(ErrNoIteratorUninitialized)
)
var errorStr = map[ErrNo]string {
    ErrNoArgumentNil: "Argument cannot be nil.",
    ErrNoArgumentNilWithName: "Argument '%s' cannot be nil.",
    ErrNoEnumeratorModified: "Enumerator has been modified while iterating.",
    ErrNoIteratorAlreadyRunning: "Iterator already running.",
    ErrNoIteratorClosed: "Iteration context closed.",
    ErrNoIteratorUninitialized: "Iteration context uninitialized.",
}
type errorDef struct {
    err ErrNo
    message string
}
func NewError(err ErrNo) error {
	return &errorDef{
        err: err, 
        message: errorStr[err],
    }
}