Improve troubleshooting doc/flows
- Use better wording for unknown server error - Add basic troubleshooting doc
This commit is contained in:
@@ -74,6 +74,9 @@ Also, check [our FAQ entry](docs/faq.md#what-kind-of-setup-is-mxisd-really-desig
|
||||
See the [dedicated document](docs/getting-started.md)
|
||||
|
||||
# Support
|
||||
## Troubleshooting
|
||||
A basic troubleshooting guide is available [here](docs/troubleshooting.md).
|
||||
|
||||
## Community
|
||||
Over Matrix: [#mxisd:kamax.io](https://matrix.to/#/#mxisd:kamax.io) ([Preview](https://view.matrix.org/room/!NPRUEisLjcaMtHIzDr:kamax.io/))
|
||||
|
||||
|
@@ -144,7 +144,8 @@ by the relevant hostname which you configured in your reverse proxy.
|
||||
**NOTE:** You might not see a suggestion for the e-mail address, which is normal. Still proceed with the invite.
|
||||
|
||||
If it worked, it means you are up and running and can enjoy mxisd in its basic mode! Congratulations!
|
||||
If it did not work, [get in touch](../README.md#support) and we'll do our best to get you started.
|
||||
If it did not work, read the basic [troubleshooting guide](troubleshooting.md), [get in touch](../README.md#support) and
|
||||
we'll do our best to get you started.
|
||||
|
||||
## Next steps
|
||||
Once your mxisd server is up and running, there are several ways you can enhance and integrate further with your
|
||||
|
53
docs/troubleshooting.md
Normal file
53
docs/troubleshooting.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Troubleshooting
|
||||
- [Purpose](#purpose)
|
||||
- [Logs](#logs)
|
||||
- [Locations](#locations)
|
||||
- [Reading Them](#reading-them)
|
||||
- [Common issues](#common-issues)
|
||||
- [Submit an issue](#submit-an-issue)
|
||||
|
||||
## Purpose
|
||||
This document describes basic troubleshooting steps for mxisd.
|
||||
|
||||
## Logs
|
||||
### Locations
|
||||
mxisd logs to `STDOUT` (Standard Output) and `STDERR` (Standard Error) only, which gets redirected
|
||||
to log file(s) depending on your system.
|
||||
|
||||
If you use the [Debian package](install/debian.md), this goes to `syslog`.
|
||||
If you use the [Docker image](install/docker.md), this goes to the container logs.
|
||||
|
||||
For any other platform, please refer to your package maintainer.
|
||||
|
||||
### Reading them
|
||||
Before reporting an issue, it is important to produce clean and complete logs so they can be understood.
|
||||
|
||||
It is usually useless to try to troubleshoot an issue based on a single log line. Any action or API request
|
||||
in mxisd would trigger more than one log lines, and those would be considered necessary context to
|
||||
understand what happened.
|
||||
|
||||
You may also find things called *stacktraces*. Those are important to pin-point bugs and the likes and should
|
||||
always be included in any report. They also tend to be very specific about the issue at hand.
|
||||
|
||||
Example of a stacktrace:
|
||||
```
|
||||
Exception in thread "main" java.lang.NullPointerException
|
||||
at com.example.myproject.Book.getTitle(Book.java:16)
|
||||
at com.example.myproject.Author.getBookTitles(Author.java:25)
|
||||
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
|
||||
```
|
||||
|
||||
### Common issues
|
||||
#### Internal Server Error
|
||||
`Contact your administrator with reference Transaction #123456789`
|
||||
|
||||
This is a generic message produced in case of an unknown error. The transaction reference allows to easily find
|
||||
the location in the logs to look for an error.
|
||||
|
||||
**IMPORTANT:** That line alone does not tell you anything about the error. You'll need the log lines before and after,
|
||||
usually including a stacktrace, to know what happened. Please take the time to read the surround output to get
|
||||
context about the issue at hand.
|
||||
|
||||
## Submit an issue
|
||||
In case the logs do not allow you to understand the issue at hand, please submit clean and complete logs
|
||||
as explained [here](#reading-them) in a new issue on the repository, or [get in touch](../README.md#contact).
|
@@ -101,6 +101,10 @@ public abstract class BasicHttpHandler implements HttpHandler {
|
||||
return GsonUtil.parseObj(getBodyUtf8(exchange));
|
||||
}
|
||||
|
||||
protected void putHeader(HttpServerExchange ex, String name, String value) {
|
||||
ex.getResponseHeaders().put(HttpString.tryFromString(name), value);
|
||||
}
|
||||
|
||||
protected void respond(HttpServerExchange ex, int statusCode, JsonElement bodyJson) {
|
||||
respondJson(ex, statusCode, GsonUtil.get().toJson(bodyJson));
|
||||
}
|
||||
|
@@ -27,8 +27,7 @@ import io.kamax.matrix.json.InvalidJsonException;
|
||||
import io.kamax.mxisd.exception.*;
|
||||
import io.undertow.server.HttpHandler;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.util.HttpString;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -37,15 +36,22 @@ import java.time.Instant;
|
||||
|
||||
public class SaneHandler extends BasicHttpHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SaneHandler.class);
|
||||
|
||||
private static final String CorsOriginName = "Access-Control-Allow-Origin";
|
||||
private static final String CorsOriginValue = "*";
|
||||
private static final String CorsMethodsName = "Access-Control-Allow-Methods";
|
||||
private static final String CorsMethodsValue = "GET, POST, PUT, DELETE, OPTIONS";
|
||||
private static final String CorsHeadersName = "Access-Control-Allow-Headers";
|
||||
private static final String CorsHeadersValue = "Origin, X-Requested-With, Content-Type, Accept, Authorization";
|
||||
|
||||
public static SaneHandler around(HttpHandler h) {
|
||||
return new SaneHandler(h);
|
||||
}
|
||||
|
||||
private transient final Logger log = LoggerFactory.getLogger(SaneHandler.class);
|
||||
private final HttpHandler child;
|
||||
|
||||
private HttpHandler child;
|
||||
|
||||
public SaneHandler(HttpHandler child) {
|
||||
private SaneHandler(HttpHandler child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
@@ -58,9 +64,9 @@ public class SaneHandler extends BasicHttpHandler {
|
||||
} else {
|
||||
try {
|
||||
// CORS headers as per spec
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("Access-Control-Allow-Origin"), "*");
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("Access-Control-Allow-Methods"), "GET, POST, PUT, DELETE, OPTIONS");
|
||||
exchange.getResponseHeaders().put(HttpString.tryFromString("Access-Control-Allow-Headers"), "Origin, X-Requested-With, Content-Type, Accept, Authorization");
|
||||
putHeader(exchange, CorsOriginName, CorsOriginValue);
|
||||
putHeader(exchange, CorsMethodsName, CorsMethodsValue);
|
||||
putHeader(exchange, CorsHeadersName, CorsHeadersValue);
|
||||
|
||||
child.handleRequest(exchange);
|
||||
} catch (IllegalArgumentException e) {
|
||||
@@ -89,9 +95,9 @@ public class SaneHandler extends BasicHttpHandler {
|
||||
handleException(exchange, e);
|
||||
} catch (InternalServerError e) {
|
||||
if (StringUtils.isNotBlank(e.getInternalReason())) {
|
||||
log.error("Reference #{} - {}", e.getReference(), e.getInternalReason());
|
||||
log.error("Transaction #{} - {}", e.getReference(), e.getInternalReason());
|
||||
} else {
|
||||
log.error("Reference #{}", e);
|
||||
log.error("Transaction #{}", e);
|
||||
}
|
||||
|
||||
handleException(exchange, e);
|
||||
@@ -105,14 +111,11 @@ public class SaneHandler extends BasicHttpHandler {
|
||||
respond(exchange, e.getStatus(), buildErrorBody(exchange, e.getErrorCode(), e.getError()));
|
||||
} catch (RuntimeException e) {
|
||||
log.error("Unknown error when handling {}", exchange.getRequestURL(), e);
|
||||
respond(exchange, HttpStatus.SC_INTERNAL_SERVER_ERROR, buildErrorBody(exchange,
|
||||
"M_UNKNOWN",
|
||||
StringUtils.defaultIfBlank(
|
||||
e.getMessage(),
|
||||
"An internal server error occurred. If this error persists, please contact support with reference #" +
|
||||
Instant.now().toEpochMilli()
|
||||
)
|
||||
));
|
||||
String message = e.getMessage();
|
||||
if (StringUtils.isBlank(message)) {
|
||||
message = "An internal server error occurred. Contact your administrator with reference Transaction #" + Instant.now().toEpochMilli();
|
||||
}
|
||||
respond(exchange, HttpStatus.SC_INTERNAL_SERVER_ERROR, buildErrorBody(exchange, "M_UNKNOWN", message));
|
||||
} finally {
|
||||
exchange.endExchange();
|
||||
}
|
||||
|
Reference in New Issue
Block a user