In my own code, I use my own error package. My observation is that a root cause of an error is special, most values in the error chain are useless except to preserve line information. Users and debuggers usually only care about the first error and the last error in the chain.
A typical formatting of an error is "Unable to ${TOP_ACTION}: ${ROOT_CAUSE}"
A typical usage of my package is: