Skip to content

Commit

Permalink
feat(hubble): warp the exception info in HugeClientUtil (#589)
Browse files Browse the repository at this point in the history
* feat(hugegraph-hubble):  constrain the message and cause returned by partial exceptions of hubble and server connection creation
  • Loading branch information
returnToInnocence authored Mar 20, 2024
1 parent fd11c1a commit 7bfcd66
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 20 deletions.
31 changes: 31 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true

[*.{java, xml, py}]
indent_style = space
indent_size = 4

[*.{java, xml}]
# Ignore the IDEA unsupported warning & it works well (indeed)
continuation_indent_size = 8
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The HugeClient class is the main entry point for interacting with a HugeGraph server.
* It provides methods for managing graphs, schemas, jobs, tasks, and other resources.
* It also implements the Closeable interface, so it can be used in a try-with-resources statement.
*/
public class HugeClient implements Closeable {

private static final Logger LOG = LoggerFactory.getLogger(RestClient.class);
Expand All @@ -51,6 +56,11 @@ public class HugeClient implements Closeable {
private AuthManager auth;
private MetricsManager metrics;

/**
* Constructs a new HugeClient using the provided builder.
*
* @param builder the HugeClientBuilder to use for configuration
*/
public HugeClient(HugeClientBuilder builder) {
this.borrowedClient = false;
RestClientConfig config;
Expand All @@ -76,6 +86,7 @@ public HugeClient(HugeClientBuilder builder) {
try {
this.initManagers(this.client, builder.graph());
} catch (Throwable e) {
// TODO: catch some exception(like IO/Network related) rather than throw Throwable
this.client.close();
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ public static void initEnv() {
}

@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(this.getClass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You 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 org.apache.hugegraph.exception;

/**
* Used to wrap other unexpected exceptions like Client/ServerException, and convert them into this.
* This is typically done to handle exceptions uniformly in the hubble UI.
*/
public class GenericException extends ParameterizedException {

public GenericException(ServerException e) {
super(e.getMessage(), e.getCause());
}

public GenericException(Exception e) {
super(e.getMessage(), e.getCause());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.hugegraph.common.Constant;
import org.apache.hugegraph.common.Response;
import org.apache.hugegraph.exception.ExternalException;
import org.apache.hugegraph.exception.GenericException;
import org.apache.hugegraph.exception.IllegalGremlinException;
import org.apache.hugegraph.exception.InternalException;
import org.apache.hugegraph.exception.ParameterizedException;
Expand Down Expand Up @@ -63,6 +64,18 @@ public Response exceptionHandler(ExternalException e) {
.build();
}

@ExceptionHandler(GenericException.class)
@ResponseStatus(HttpStatus.OK)
public Response exceptionHandler(GenericException e) {
log.error("GenericException:", e);
return Response.builder()
.status(Constant.STATUS_BAD_REQUEST)
.message("Faied to connect the graph server. Please refer to the " +
"Hubble log for details.")
.cause(null)
.build();
}

@ExceptionHandler(ParameterizedException.class)
@ResponseStatus(HttpStatus.OK)
public Response exceptionHandler(ParameterizedException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.hugegraph.driver.HugeClient;
import org.apache.hugegraph.entity.GraphConnection;
import org.apache.hugegraph.exception.ExternalException;
import org.apache.hugegraph.exception.GenericException;
import org.apache.hugegraph.exception.ServerException;
import org.apache.hugegraph.rest.ClientException;
import org.apache.hugegraph.structure.gremlin.Result;
Expand All @@ -48,15 +49,12 @@ public static HugeClient tryConnect(GraphConnection connection) {
String password = connection.getPassword();
int timeout = connection.getTimeout();
String protocol = connection.getProtocol() == null ?
DEFAULT_PROTOCOL :
connection.getProtocol();
DEFAULT_PROTOCOL : connection.getProtocol();
String trustStoreFile = connection.getTrustStoreFile();
String trustStorePassword = connection.getTrustStorePassword();

String url = UriComponentsBuilder.newInstance()
.scheme(protocol)
.host(host).port(port)
.toUriString();
.scheme(protocol).host(host).port(port).toUriString();
if (username == null) {
username = "";
password = "";
Expand Down Expand Up @@ -84,15 +82,12 @@ public static HugeClient tryConnect(GraphConnection connection) {
String message = e.getMessage();
if (Constant.STATUS_UNAUTHORIZED == e.status() ||
(message != null && message.startsWith("Authentication"))) {
throw new ExternalException(
"graph-connection.username-or-password.incorrect", e);
throw new ExternalException("graph-connection.username-or-password.incorrect", e);
}
if (message != null && message.contains("Invalid syntax for " +
"username and password")) {
throw new ExternalException(
"graph-connection.missing-username-password", e);
if (message != null && message.contains("Invalid syntax for username and password")) {
throw new ExternalException("graph-connection.missing-username-password", e);
}
throw e;
throw new GenericException(e);
} catch (ClientException e) {
Throwable cause = e.getCause();
if (cause == null || cause.getMessage() == null) {
Expand All @@ -105,24 +100,23 @@ public static HugeClient tryConnect(GraphConnection connection) {
message.contains("Host name may not be null")) {
throw new ExternalException("service.unknown-host", e, host);
} else if (message.contains("<!doctype html>")) {
throw new ExternalException("service.suspected-web",
e, host, port);
throw new ExternalException("service.suspected-web", e, host, port);
}
throw e;
} catch (Exception e) {
throw new GenericException(e);
}

try {
ResultSet rs = client.gremlin().gremlin("g.V().limit(1)").execute();
rs.iterator().forEachRemaining(Result::getObject);
} catch (ServerException e) {
if (Constant.STATUS_UNAUTHORIZED == e.status()) {
throw new ExternalException(
"graph-connection.username-or-password.incorrect", e);
throw new ExternalException("graph-connection.username-or-password.incorrect", e);
}
String message = e.message();
if (message != null && message.contains("Could not rebind [g]")) {
throw new ExternalException("graph-connection.graph.unexist", e,
graph, host, port);
throw new ExternalException("graph-connection.graph.unexist", e, graph, host, port);
}
if (!isAcceptable(message)) {
throw e;
Expand Down
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,14 @@
<goal>clean</goal>
</goals>
</execution>
<!-- auto delete .flattened-pom.xml after "install" step, will influence deploy step now-->
<!--execution>
<id>remove-flattened-pom</id>
<phase>install</phase>
<goals>
<goal>clean</goal>
</goals>
</execution-->
</executions>
</plugin>
</plugins>
Expand Down

0 comments on commit 7bfcd66

Please sign in to comment.