Skip to content

Commit

Permalink
Improve troubleshooting doc/flows
Browse files Browse the repository at this point in the history
- Use better wording for unknown server error
- Add basic troubleshooting doc
  • Loading branch information
maxidorius committed Feb 17, 2019
1 parent 99697d7 commit 249cc0e
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 20 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/))

Expand Down
3 changes: 2 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
53 changes: 53 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -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).
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ protected JsonObject parseJsonObject(HttpServerExchange exchange) {
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));
}
Expand Down
41 changes: 22 additions & 19 deletions src/main/java/io/kamax/mxisd/http/undertow/handler/SaneHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
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;
Expand All @@ -37,15 +36,22 @@

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;
}

Expand All @@ -58,9 +64,9 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
} 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) {
Expand Down Expand Up @@ -89,9 +95,9 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
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);
Expand All @@ -105,14 +111,11 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
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();
}
Expand Down

0 comments on commit 249cc0e

Please sign in to comment.