Improve the extensions page when things go wrong.

Previously, the extensions page didn't handle errors all that well. An
extension whose module couldn't even be loaded (due to an import or
syntax error) would end up causing an HTTP 500 when accessing the
extensions list resource. Trying to enable an extension that had an
error would show an alert with just the exception message and nothing
else of value.

This does a fairly large overhaul to the whole thing by storing load
error information and making them available through the API, both in
resource payloads and error payloads. It also sanitizes the fields in
the resource payloads in order to not crash.

Now, the extensions page will show a traceback along with the extension.
This is shown for any broken extensions on page load, or when attempting
to enable a broken extension.

An extension that has a failure simply in initialization (rather than a
module error) will provide the option to enable the extension, but those
with a module error will not. This is because a full reload is needed to
try loading that module again. To solve this case, a "Reload" button
will be provided any time an error is shown, which will trigger a full
extension manager reload. This all makes it much easier to develop
extensions and see what's wrong.

Trying to enable a broken extension also no longer records it as being
enabled. It will stay disabled unless it enables successfully.

While here, I did some bits of cleanup to the JavaScript and to the
display. Since we now have reload functionality, I added a link to
trigger a reload in order to find newly installed extensions. I also
added some color-based hints to show the state of an extension (enabled,
disabled, error).