Improved exception handling for 301, null response body and connection issues
This commit is contained in:
parent
6f9fba2c51
commit
bc3c576dc6
5 changed files with 172 additions and 86 deletions
|
@ -17,6 +17,7 @@ package com.rohitawate.restaurant.dashboard;
|
|||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
|
||||
import com.rohitawate.restaurant.models.requests.DELETERequest;
|
||||
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
|
||||
import com.rohitawate.restaurant.models.requests.GETRequest;
|
||||
|
@ -37,13 +38,12 @@ import javafx.scene.layout.BorderPane;
|
|||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
@ -115,6 +115,9 @@ public class DashboardController implements Initializable {
|
|||
snackBar = new JFXSnackbar(dashboard);
|
||||
bodyTab.disableProperty().bind(Bindings.and(httpMethodBox.valueProperty().isNotEqualTo("POST"),
|
||||
httpMethodBox.valueProperty().isNotEqualTo("PUT")));
|
||||
|
||||
errorTitle.setText("Oops... That's embarrassing!");
|
||||
errorDetails.setText("Something went wrong. Try to make another request.\nRestart RESTaurant if that doesn't work.");
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
@ -166,13 +169,18 @@ public class DashboardController implements Initializable {
|
|||
});
|
||||
requestManager.setOnFailed(e -> {
|
||||
loadingLayer.setVisible(false);
|
||||
errorLayer.setVisible(true);
|
||||
Throwable exception = requestManager.getException().getCause();
|
||||
promptLayer.setVisible(false);
|
||||
Throwable exception = requestManager.getException();
|
||||
|
||||
if (exception.getClass() == UnknownHostException.class) {
|
||||
errorTitle.setText("No Internet Connection");
|
||||
errorDetails.setText("Could not connect to the server. Please check your connection.");
|
||||
if (exception.getClass() == UnreliableResponseException.class) {
|
||||
UnreliableResponseException URE = (UnreliableResponseException) exception;
|
||||
errorTitle.setText(URE.getExceptionTitle());
|
||||
errorDetails.setText(URE.getExceptionDetails());
|
||||
} else if (exception.getClass() == ProcessingException.class) {
|
||||
errorTitle.setText("RESTaurant couldn't connect.");
|
||||
errorDetails.setText("Either you are not connected to the Internet or the server is offline.");
|
||||
}
|
||||
errorLayer.setVisible(true);
|
||||
requestManager.reset();
|
||||
});
|
||||
requestManager.start();
|
||||
|
@ -213,11 +221,19 @@ public class DashboardController implements Initializable {
|
|||
});
|
||||
requestManager.setOnFailed(e -> {
|
||||
loadingLayer.setVisible(false);
|
||||
promptLayer.setVisible(true);
|
||||
if (requestManager.getException().getClass() == ConnectException.class)
|
||||
snackBar.show("Request timed out. Server is unavailable or didn't respond.", 10000);
|
||||
else if (requestManager.getException().getClass() == FileNotFoundException.class)
|
||||
promptLayer.setVisible(false);
|
||||
Throwable exception = requestManager.getException();
|
||||
|
||||
if (exception.getClass() == UnreliableResponseException.class) {
|
||||
UnreliableResponseException URE = (UnreliableResponseException) exception;
|
||||
errorTitle.setText(URE.getExceptionTitle());
|
||||
errorDetails.setText(URE.getExceptionDetails());
|
||||
} else if (exception.getClass() == ProcessingException.class) {
|
||||
errorTitle.setText("RESTaurant couldn't connect.");
|
||||
errorDetails.setText("Either you are not connected to the Internet or the server is offline.");
|
||||
} else if (exception.getClass() == FileNotFoundException.class)
|
||||
snackBar.show("File could not be found.", 5000);
|
||||
errorLayer.setVisible(true);
|
||||
requestManager.reset();
|
||||
});
|
||||
requestManager.start();
|
||||
|
@ -253,13 +269,18 @@ public class DashboardController implements Initializable {
|
|||
});
|
||||
requestManager.setOnFailed(e -> {
|
||||
loadingLayer.setVisible(false);
|
||||
errorLayer.setVisible(true);
|
||||
Throwable exception = requestManager.getException().getCause();
|
||||
promptLayer.setVisible(false);
|
||||
Throwable exception = requestManager.getException();
|
||||
|
||||
if (exception.getClass() == UnknownHostException.class) {
|
||||
if (exception.getClass() == UnreliableResponseException.class) {
|
||||
UnreliableResponseException URE = (UnreliableResponseException) exception;
|
||||
errorTitle.setText(URE.getExceptionTitle());
|
||||
errorDetails.setText(URE.getExceptionDetails());
|
||||
} else if (exception.getClass() == ProcessingException.class) {
|
||||
errorTitle.setText("No Internet Connection");
|
||||
errorDetails.setText("Could not connect to the server. Please check your connection.");
|
||||
}
|
||||
errorLayer.setVisible(true);
|
||||
requestManager.reset();
|
||||
});
|
||||
requestManager.start();
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2018 Rohit Awate.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.rohitawate.restaurant.exceptions;
|
||||
|
||||
/**
|
||||
* Thrown when the server sends ambiguous responses.
|
||||
* For example, some servers do not provide the new location in case of a 301 Moved Permanently.
|
||||
* <p>
|
||||
* Used by DashboardController to display ErrorLayer.
|
||||
*/
|
||||
public class UnreliableResponseException extends Exception {
|
||||
private String exceptionTitle;
|
||||
private String exceptionDetails;
|
||||
|
||||
public UnreliableResponseException(String exceptionTitle, String exceptionDetails) {
|
||||
this.exceptionTitle = exceptionTitle;
|
||||
this.exceptionDetails = exceptionDetails;
|
||||
}
|
||||
|
||||
public void setExceptionTitle(String exceptionTitle) {
|
||||
this.exceptionTitle = exceptionTitle;
|
||||
}
|
||||
|
||||
public void setExceptionDetails(String exceptionDetails) {
|
||||
this.exceptionDetails = exceptionDetails;
|
||||
}
|
||||
|
||||
public String getExceptionTitle() {
|
||||
return exceptionTitle;
|
||||
}
|
||||
|
||||
public String getExceptionDetails() {
|
||||
return exceptionDetails;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package com.rohitawate.restaurant.requestsmanager;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
|
||||
import com.rohitawate.restaurant.models.requests.DELETERequest;
|
||||
import com.rohitawate.restaurant.models.responses.RestaurantResponse;
|
||||
import javafx.concurrent.Task;
|
||||
|
@ -26,7 +27,6 @@ import javafx.concurrent.Task;
|
|||
import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -58,22 +58,22 @@ public class DELETERequestManager extends RequestManager {
|
|||
response.setTime(initialTime, System.currentTimeMillis());
|
||||
|
||||
if (serverResponse == null)
|
||||
throw new IOException();
|
||||
throw new UnreliableResponseException("The server did not respond.",
|
||||
"Like that crush from high school..");
|
||||
else if (serverResponse.getStatus() == 301) {
|
||||
response.setStatusCode(301);
|
||||
String newLocation = serverResponse.getHeaderString("location");
|
||||
String responseHelpText;
|
||||
|
||||
String responseHelpText;
|
||||
if (newLocation == null)
|
||||
responseHelpText = "The resource has been permanently moved to another location.\n\n" +
|
||||
responseHelpText = "The resource has been permanently moved to another location.\n" +
|
||||
"Here's what you can do:\n" +
|
||||
"- Find the new URL from the API documentation.\n" +
|
||||
"- Try using https instead of http if you're not already.";
|
||||
else
|
||||
responseHelpText = "The resource has been permanently moved to: " + newLocation;
|
||||
responseHelpText = "The resource has been permanently moved to: " + newLocation +
|
||||
"\nRESTaurant doesn't automatically redirect your requests.";
|
||||
|
||||
response.setBody(responseHelpText);
|
||||
return response;
|
||||
throw new UnreliableResponseException("301: Resource Moved Permanently", responseHelpText);
|
||||
}
|
||||
|
||||
String type = (String) serverResponse.getHeaders().getFirst("Content-type");
|
||||
|
@ -82,22 +82,26 @@ public class DELETERequestManager extends RequestManager {
|
|||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
case "application/json; charset=utf-8":
|
||||
case "application/json":
|
||||
JsonNode node = mapper.readTree(responseBody);
|
||||
response.setBody(mapper.writeValueAsString(node));
|
||||
break;
|
||||
case "application/xml; charset=utf-8":
|
||||
case "application/xml":
|
||||
response.setBody(mapper.writeValueAsString(responseBody));
|
||||
break;
|
||||
case "text/html":
|
||||
case "text/html; charset=utf-8":
|
||||
response.setBody(responseBody);
|
||||
break;
|
||||
default:
|
||||
response.setBody(responseBody);
|
||||
if (type != null) {
|
||||
switch (type.toLowerCase()) {
|
||||
case "application/json; charset=utf-8":
|
||||
case "application/json":
|
||||
JsonNode node = mapper.readTree(responseBody);
|
||||
response.setBody(mapper.writeValueAsString(node));
|
||||
break;
|
||||
case "application/xml; charset=utf-8":
|
||||
case "application/xml":
|
||||
response.setBody(mapper.writeValueAsString(responseBody));
|
||||
break;
|
||||
case "text/html":
|
||||
case "text/html; charset=utf-8":
|
||||
response.setBody(responseBody);
|
||||
break;
|
||||
default:
|
||||
response.setBody(responseBody);
|
||||
}
|
||||
} else {
|
||||
response.setBody("No body found in the response.");
|
||||
}
|
||||
|
||||
response.setMediaType(serverResponse.getMediaType());
|
||||
|
|
|
@ -19,6 +19,7 @@ package com.rohitawate.restaurant.requestsmanager;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
|
||||
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
|
||||
import com.rohitawate.restaurant.models.responses.RestaurantResponse;
|
||||
import javafx.concurrent.Task;
|
||||
|
@ -32,7 +33,10 @@ import javax.ws.rs.client.WebTarget;
|
|||
import javax.ws.rs.core.Form;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -132,22 +136,22 @@ public class DataDispatchRequestManager extends RequestManager {
|
|||
response.setTime(initialTime, System.currentTimeMillis());
|
||||
|
||||
if (serverResponse == null)
|
||||
throw new IOException();
|
||||
throw new UnreliableResponseException("The server did not respond.",
|
||||
"Like that crush from high school..");
|
||||
else if (serverResponse.getStatus() == 301) {
|
||||
response.setStatusCode(301);
|
||||
String newLocation = serverResponse.getHeaderString("location");
|
||||
String responseHelpText;
|
||||
|
||||
String responseHelpText;
|
||||
if (newLocation == null)
|
||||
responseHelpText = "The resource has been permanently moved to another location.\n\n" +
|
||||
responseHelpText = "The resource has been permanently moved to another location.\n" +
|
||||
"Here's what you can do:\n" +
|
||||
"- Find the new URL from the API documentation.\n" +
|
||||
"- Try using https instead of http if you're not already.";
|
||||
else
|
||||
responseHelpText = "The resource has been permanently moved to: " + newLocation;
|
||||
responseHelpText = "The resource has been permanently moved to: " + newLocation +
|
||||
"\nRESTaurant doesn't automatically redirect your requests.";
|
||||
|
||||
response.setBody(responseHelpText);
|
||||
return response;
|
||||
throw new UnreliableResponseException("301: Resource Moved Permanently", responseHelpText);
|
||||
}
|
||||
|
||||
String type = (String) serverResponse.getHeaders().getFirst("Content-type");
|
||||
|
@ -156,22 +160,26 @@ public class DataDispatchRequestManager extends RequestManager {
|
|||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
case "application/json; charset=utf-8":
|
||||
case "application/json":
|
||||
JsonNode node = mapper.readTree(responseBody);
|
||||
response.setBody(mapper.writeValueAsString(node));
|
||||
break;
|
||||
case "application/xml; charset=utf-8":
|
||||
case "application/xml":
|
||||
response.setBody(mapper.writeValueAsString(responseBody));
|
||||
break;
|
||||
case "text/html":
|
||||
case "text/html; charset=utf-8":
|
||||
response.setBody(responseBody);
|
||||
break;
|
||||
default:
|
||||
response.setBody(responseBody);
|
||||
if (type != null) {
|
||||
switch (type.toLowerCase()) {
|
||||
case "application/json; charset=utf-8":
|
||||
case "application/json":
|
||||
JsonNode node = mapper.readTree(responseBody);
|
||||
response.setBody(mapper.writeValueAsString(node));
|
||||
break;
|
||||
case "application/xml; charset=utf-8":
|
||||
case "application/xml":
|
||||
response.setBody(mapper.writeValueAsString(responseBody));
|
||||
break;
|
||||
case "text/html":
|
||||
case "text/html; charset=utf-8":
|
||||
response.setBody(responseBody);
|
||||
break;
|
||||
default:
|
||||
response.setBody(responseBody);
|
||||
}
|
||||
} else {
|
||||
response.setBody("No body found in the response.");
|
||||
}
|
||||
|
||||
response.setMediaType(serverResponse.getMediaType());
|
||||
|
|
|
@ -19,13 +19,13 @@ package com.rohitawate.restaurant.requestsmanager;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
|
||||
import com.rohitawate.restaurant.models.responses.RestaurantResponse;
|
||||
import javafx.concurrent.Task;
|
||||
|
||||
import javax.ws.rs.client.Invocation.Builder;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -53,22 +53,22 @@ public class GETRequestManager extends RequestManager {
|
|||
response.setTime(initialTime, System.currentTimeMillis());
|
||||
|
||||
if (serverResponse == null)
|
||||
throw new IOException();
|
||||
throw new UnreliableResponseException("The server did not respond.",
|
||||
"Like that crush from high school..");
|
||||
else if (serverResponse.getStatus() == 301) {
|
||||
response.setStatusCode(301);
|
||||
String newLocation = serverResponse.getHeaderString("location");
|
||||
String responseHelpText;
|
||||
|
||||
String responseHelpText;
|
||||
if (newLocation == null)
|
||||
responseHelpText = "The resource has been permanently moved to another location.\n\n" +
|
||||
responseHelpText = "The resource has been permanently moved to another location.\n" +
|
||||
"Here's what you can do:\n" +
|
||||
"- Find the new URL from the API documentation.\n" +
|
||||
"- Try using https instead of http if you're not already.";
|
||||
else
|
||||
responseHelpText = "The resource has been permanently moved to: " + newLocation;
|
||||
responseHelpText = "The resource has been permanently moved to: " + newLocation +
|
||||
"\nRESTaurant doesn't automatically redirect your requests.";
|
||||
|
||||
response.setBody(responseHelpText);
|
||||
return response;
|
||||
throw new UnreliableResponseException("301: Resource Moved Permanently", responseHelpText);
|
||||
}
|
||||
|
||||
String type = (String) serverResponse.getHeaders().getFirst("Content-type");
|
||||
|
@ -77,22 +77,26 @@ public class GETRequestManager extends RequestManager {
|
|||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
case "application/json; charset=utf-8":
|
||||
case "application/json":
|
||||
JsonNode node = mapper.readTree(responseBody);
|
||||
response.setBody(mapper.writeValueAsString(node));
|
||||
break;
|
||||
case "application/xml; charset=utf-8":
|
||||
case "application/xml":
|
||||
response.setBody(mapper.writeValueAsString(responseBody));
|
||||
break;
|
||||
case "text/html":
|
||||
case "text/html; charset=utf-8":
|
||||
response.setBody(responseBody);
|
||||
break;
|
||||
default:
|
||||
response.setBody(responseBody);
|
||||
if (type != null) {
|
||||
switch (type.toLowerCase()) {
|
||||
case "application/json; charset=utf-8":
|
||||
case "application/json":
|
||||
JsonNode node = mapper.readTree(responseBody);
|
||||
response.setBody(mapper.writeValueAsString(node));
|
||||
break;
|
||||
case "application/xml; charset=utf-8":
|
||||
case "application/xml":
|
||||
response.setBody(mapper.writeValueAsString(responseBody));
|
||||
break;
|
||||
case "text/html":
|
||||
case "text/html; charset=utf-8":
|
||||
response.setBody(responseBody);
|
||||
break;
|
||||
default:
|
||||
response.setBody(responseBody);
|
||||
}
|
||||
} else {
|
||||
response.setBody("No body found in the response.");
|
||||
}
|
||||
|
||||
response.setMediaType(serverResponse.getMediaType());
|
||||
|
|
Loading…
Reference in a new issue