I'm using ionic and capacitor v2.5 for creating a plugin
I'm using the following code for catching unhandled exception in the capacitor plugin
public void load() {
super.load();
try {
Thread
.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable e) {
PluginCall call = getSavedCall();
if (call != null) {
call.error("called failed:"+e.getMessage());
}
freeSavedCall();
}
});
} catch (SecurityException e) {
Log.e(Constants.TAG_MASTER,
"Could not set the Default Uncaught Exception Handler:"
+ e.getStackTrace());
}
}
my problem is that whenever there is an unhandled exception, the plugin stop to respond to calls from the ionic app.
The code operates as "expected" in a sense that gets the call from the method that throwed the exception and the call.error(..); is executed.
I can replicate that with the following code
public void foo(PluginCall call) {
saveCall(call);
throw new exception();
}
Any thoughts on why the plugin stops to respond after that?
Related
When handling errors in my cmdlet development, I encounter an unexpected behavior of the ThrowTerminatingError method.
Calling the method results in an unhandled exception of PipelineStoppedException. Thus, I do not get a formatted error in PowerShell, but a long unhandled exception error message.
My code corresponds to the following structure:
protected override async void ProcessRecord()
{
try
{
var transferClient = new TransferClient(...);
var result = await transferClient.GetAsync(); // Throws an AuthenticationException
}
catch (AuthenticationException exception)
{
var record = new ErrorRecord(exception, "TestException", ErrorCategory.AuthenticationError, null);
ThrowTerminatingError(record); // Unhandled exception
}
}
System info:
Microsoft.PowerShell.SDK: 7.2.8
System.Management.Automation: 7.2.8
Target: PowerShell 7
I'm using WebSocket variable in my MyWebSocket class. For listen i give a callback function as parameter.
If this callback function throws an exception in calling class MyChat, then i can not catch that exception anywhere.
My simplified code is:
class MyWebSocket {
WebSocket _ws;
...
// initialized in controller: _ws = WebSocket.connect(_some_url_);
// everything works (connect, listen)
...
void listen({void Function(dynamic) myOnListen}) {
try {
_ws.listen(myOnListen)
.onError((e) => print("MyWebSocket in MyChat.onError: $e"));
} catch (e) {
print("Catched in MyWebSocket: $e");
}
}
}
class MyChat {
MyWebSocket _chatWs = MyWebSocket();
...
void initWS() {
try {
_chatWs.listen(myOnListen: processMsg);
} catch (e) {
print("Catched in MyChat: $e");
}
}
void processMsg(dynamic msg) {
if(_some_stuff_like_invalid_msg_or_not_logged_in_...)
throw Exception("There is my Exception");
}
}
I have built try-catch in every possible place to catch exceptions - no success, i got only unhandled exception:
E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: Exception: There is my Exception
E/flutter: #0 MyChat.processMsg
Beware that you cannot use the passed listener as a key for later removal. For that you can pass the new listener created in MyWebSocket class when listen() is called, then use this key to remove the listener.
class MyWebSocket {
WebSocket _ws;
void listen({void Function(dynamic) myOnListen, void Function(Error) onError}) {
try {
_ws.listen((){
try {
myOnListen({"label": "DATA"});
} catch (e) {
if(onError is Function)
onError(e)
}
})
.onError(onError);
} catch (e) {
print("Catched in MyWebSocket: $e");
}
}
}
class MyChat {
MyWebSocket _chatWs = MyWebSocket();
void initWS() {
try {
_chatWs.listen(myOnListen: processMsg, onError: (Error error){
print("ERROR: "+error.toString());
});
} catch (e) {
print("Catched in MyChat: $e");
}
}
void processMsg(dynamic msg) {
if(_some_stuff_like_invalid_msg_or_not_logged_in_...)
throw Exception("There is my Exception");
}
}
You need to handle it inside your processMsg
If you analyze carefully the execution of your code the _ws.listent register a listener for when you receive a message and that will happen in the FUTURE, but you don't get an error WHILE you are REGISTERING your listener that's why that doesn't work the way you expect.
processMsg will do something in the future, it will throw an error and it's at the end of the pipeline.
You are simulating an exception and nothing is handling it, it happens in a different stack frame, in the future.
The void listen({void Function(dynamic) myOnListen}) function execution is long gone when you receive and you precessMsg.
Alternatively you could do:
Function tryCatchHOF(Function cb) {
decorated(dynamic param) {
try {
cb(param);
} catch (e) {
print("$e");
}
}
;
return decorated;
}
void processMsg(dynamic msg) {
if (true) throw Exception("There is my Exception");
}
var processMsgWithTryCatch = tryCatchHOF(processMsg);
processMsgWithTryCatch('');
and then pass processMsgWithTryCatch down to your listener if you don't want to handle inside processMsg
I hope that make sense
I used ListeningExecutorService of guava in my project, got confused about the exception handling.
I used a thread pool, submit a task to it, and set a timeout to the listenableFuture, and add a callback to it.
final ListeningExecutorService threadPool = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
Futures.addCallback(listenableFuture, new FutureCallback<**>() {
#Override
public void onSuccess(#Nullable ** data) {
xxxxxxx;
}
public void onFailure(Throwable t) {
xxxxxxxxxx;
if (t instanceof CancellationException) {
throw new QueryException("yyyy");
} else {
throw new QueryException("zzzzz");
}
}
});
I can't catch the exception inside the callback. So I use another ListenableFuture to get the exception
ListenableFuture allFutures = Futures.allAsList(allFuturesList);
try {
allFutures.get();
} catch (CancellationException ce) {
throw new QueryException("");
} catch (InterruptedException t) {
throw new QueryException("");
} catch (ExecutionException e) {
Throwable t = e.getCause();
if (t instanceof QueryException)
throw (QueryException) t;
else
throw new QueryException();
} catch (QueryException qe) {
throw qe;
} catch (Exception e) {
throw new QueryException();
} finally {
}
But I when the callback throw a QueryException, the allFutures can't catch it, allFutures can only catch a CancellationException without the detail error message.
How can I get my detail error message?
Futures.allAsList doesn't do what you expect it to do
From the Javadoc: (emphasis is from me)
Canceling this future will attempt to cancel all the component futures, and if any of the provided futures fails or is canceled, this one is, too.
What you should probably do is create your own aggregating future. You can base your code on Guava's own internal mechanism. See the source code for more info.
Anyways, do not throw exceptions in your FutureCallback::onFailure method.
I am currently using gwt-resty and jersey for the server side. The problem I have run into is how do I map an exception for the MethodCallback implementation. I have created an ExceptionMapper which converts the exception to json and returns it in json format but the onFailure method is giving me the generic error message for my exception, "Failed BAD Request"
The question is how do I convert the exception into something that gwt-resty can process the exception in order to get the message from the server side exception.
Here is my service implementation
service.getCurrentAddress("123456", new MethodCallback<Address>() {
#Override
public void onSuccess(Method method, Address response) {
Window.alert("Got your address" + response);
}
#Override
public void onFailure(Method method, Throwable e) {
GWT.log("failed", e);
GWT.log("Failed " + e.getMessage());
}
});
}
Here is my exception mapper.
#Provider
public class VendorExceptionMapper implements ExceptionMapper<Exception> {
#Override
public Response toResponse(Exception exception) {
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON).entity(exception).build();
}
}
I am not sure I understood your question but I think that you can parse Throwable e to get your exception in case of failure.
You can also intercept your exception by coding a restyGWT dispatcher and treat it before entering the onFailure().
I try to use get result from a api called j-calais, and then out put the result on a web page, i write all the code in client, but it cant compile right, dont know why??? please help. the source code like below:
there is no obvious error arise, but it cant be compile successfully..... thanks a lot:
public void onModuleLoad() {
// Create table for stock data.
stocksFlexTable.setText(0, 0, "Type");
stocksFlexTable.setText(0, 1, "Name");
// Assemble Add Stock panel.
addPanel.add(newSymbolTextBox);
addPanel.add(addStockButton);
// Assemble Main panel.
mainPanel.add(stocksFlexTable);
mainPanel.add(addPanel);
mainPanel.add(lastUpdatedLabel);
// Associate the Main panel with the HTML host page.
RootPanel.get("stockList").add(mainPanel);
// Move cursor focus to the input box.
newSymbolTextBox.setFocus(true);
// Listen for mouse events on the Add button.
addStockButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
try {
addStock();
} catch (Exception e) {
e.printStackTrace();
}
}
});
// Listen for keyboard events in the input box.
newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
public void onKeyPress(KeyPressEvent event) {
if (event.getCharCode() == KeyCodes.KEY_ENTER) {
try {
addStock();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
private void addStock() throws Exception {
final String url_s = newSymbolTextBox.getText().toUpperCase().trim();
newSymbolTextBox.setFocus(true);
newSymbolTextBox.setText("");
int row = stocksFlexTable.getRowCount();
CalaisClient client = new CalaisRestClient("ysw5rx69jkvdnzqf6sgjduqj");
System.out.print("read success...\n");
URL url = new URL(url_s);
CalaisResponse response = client.analyze(url);
for (CalaisObject entity : response.getEntities()) {
System.out.println(entity.getField("_type") + ":"
+ entity.getField("name"));
stocks.add(entity.getField("_type"));
stocksFlexTable.setText(row, 0, entity.getField("_type"));
stocksFlexTable.setText(row, 1, entity.getField("name"));
}
for (CalaisObject topic : response.getTopics()) {
System.out.println(topic.getField("categoryName"));
}
}
}
GWT only handles unchecked exceptions so you can throw Runtime Exceptions
or write your own Exception that extends from Runtime Exception then it will not cause any compile time problem
void f() throws NullPointerException // will not cause any problem because it is Runtime exception so unchecked
void f() throws IllegalAccessException // it is checked exception so there will be problem at compile time