Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clients can't catch exceptions when they call some methods in the EZIDClient class which run in different threads #17

Open
taojing2002 opened this issue Nov 14, 2023 · 1 comment

Comments

@taojing2002
Copy link

In the EZIDClient class, methods such as, create, createOrUpdate, setMetadata, and delete run on a different thread. When errors happen in another thread, it only logs in a file. So this cause clients can't capture the exception. Here is a ticket to describe the issue in Metacat:
NCEAS/metacat#1545

We need provide a mechanism for client to catch the exceptions even though we still keep the multi-thread feature.

@taojing2002
Copy link
Author

taojing2002 commented Nov 29, 2023

Here is my proposal.
First, change the class of EZIDServiceRequest to implement the Callable interface rather than Runnable interface. The call method in the Callable interface can throw an exception but the run method in the Runnable interface can't. So the method can be:

public String call() throws EZIDException {
    String result = "success" ;
    .......
    return result;
}

The EZIDException will not be swallowed by the call method. Currently, we just log the error message in the run method if the exception raises.

In order for the client to get the thrown exception, we need give the client a Future object. Here is our current implementation of the setMetadata method in the EZIDClient class:

public void setMetadata(String identifier, HashMap<String, String> metadata) throws InterruptedException {
        EZIDServiceRequest request = new EZIDServiceRequest(ezid, EZIDServiceRequest.SETMETADATA, identifier, metadata);
        executor.execute(request);
}

Here is the new implementation and it returns a Future object:

public Future<String> setMetadata(String identifier, HashMap<String, String> metadata) throws InterruptedException {
        EZIDServiceRequest request = new EZIDServiceRequest(ezid, EZIDServiceRequest.SETMETADATA, identifier, metadata);
        return executor.submit(request);
}

When the client calls the setMetadata method, it has a Future object and it can check if an exception happened in the other thread like this:

Future future = ezid.setMetadata(id, metadata);
try {
       future.get()); 
} catch (ExecutionException ex) {
       relogin();
}

The EzidException thrown by the call method will be wrapped by the ExecutionException when we call future.get(). So the client can catch the exception and re-login.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant