The current plan, as being developed on the dev branch, is to use an error stack. 'Nested' errors are not used, but every error in the stack is caused by the next one. The stack rotates in such a way to keep the outermost errors only. Two different kinds of errors - debug and non-debug - will be differentiated so that debug errors are only saved when debugging is enabled. This differentiation could be made by error type - for example, a bad input error from a function is generally an internal error and so should only be saved when debugging - or it could be made a separate variable. I'm probably looking at the latter. The terminology to use - debugging/non-debugging or internal/external - is not yet fixed.
There's also quite a bit of processing that goes on for things like headers and images. If cmark-gfm can support hooks that allow modifying the Markdown/HTML being processed, that would work, but otherwise see my current PR https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/10449.
Up till now, statme was not affected at all by the user. Errors, while well-formatted, were intended for developers (i.e. me) rather than end users. However, now that things like configuration are coming to statme, it is important that end-user errors and internal errors be differentiated. This requires a complete overhaul of the error system.
It is possible that internal errors and external (end-user) errors will be completely separate, so that both can be reported should something bad happen. Importantly, internal errors should report the name of the module from which the error originates instead of the function. It would be better if this behaviour could be switched at compile-time, for more debugging behaviour. The difference between the two could be implemented simply based on the error type, changing the interpretation of the 'function' field into a 'module' field (via unions).
A new method of handling errors may be to pass a pointer to an error structure to functions that can result in errors. If an error 'stack' is given, then a high-level backtrace-like system can be provided, which may be useful (note: this idea is stolen/inspired by Zig). A single stack would be used even if internal and external errors are separate.
This error stack system would not play so well with functions that might not return an error even if an internal function does, as they would have to allocate their own stack, check for errors there, and copy the error to their own stack if necessary. This situation occurs, for example, when an internal function reports that it is not ready, but the caller function calls it again and again until it succeeds.
I have also wanted more descriptive errors for things like 'bad input'. One idea was to have nested errors, so that situations like 'configuration error - value missing' would be encoded as two errors for more flexibility. This would go well with the error stack idea above, provided that nested errors are overwritten in such a way that the 'child' error is never 'orphaned', as that would make the error uninformative (or 'orphaned' errors could still be kept - I don't know).
One important thing to watch out for, which should be easy to prevent, is accidently making infinitely nested errors. It should be easy to prevent.
We're still using misaka, which is not good, and bugs about markdown formatting are piling up from multiple bug trackers, so I think it would be a good idea to replace misaka with something else. See https://todo.sr.ht/~sircmpwn/sr.ht/223, https://todo.sr.ht/~sircmpwn/sr.ht/195, https://todo.sr.ht/~sircmpwn/sr.ht/188, https://todo.sr.ht/~sircmpwn/sr.ht/127, https://todo.sr.ht/~sircmpwn/git.sr.ht/201, https://todo.sr.ht/~sircmpwn/git.sr.ht/191, and that was only a cursory search.
As mentioned before, there is https://github.com/rtfd/CommonMark-py, and I found https://pypi.org/project/marko, which implements CommonMark, adds additional extensions and has GFM support. However, it clearly states that it's a bit slower than other processors; I don't know whether this is going to be an issue.
I don't program often in Python, but I am willing to try to rewrite https://git.sr.ht/~sircmpwn/core.sr.ht/tree/master/srht/markdown.py to use marko instead. There will probably be a lot of bugs, but I can put forth a first implementation.