How to do exception handling in flux - project-reactor

Exception is thrown from one flux but second flux is not able to catch it. Is there anything missing in this code?
public static void main(String[] args) {
Flux<Integer> fluxFromJust = Flux.just(1, 2,3,4,5);
fluxFromJust.doOnNext(t -> {
try {
test();
} catch (Exception exception) {
//System.out.println("------hello-------");
}
}).subscribe();
}
public static void test() throws Exception{
Flux<Integer> fluxFromJust = Flux.just(1, 2,3,4,5)
.concatWith(Flux.error(new RuntimeException("Test")))
.concatWith(Flux.just(6))
.map(i->i*2)
.onErrorMap(e -> new Exception(e) );
fluxFromJust.subscribe();
}
}```
Catch of the calling function is not called. Is there anything missing?

Related

Is there an solution for java.lang.IllegalStateException: Reply already submitted

I want to use pusher sdk in Flutter from android native code because its library no yet completely supported in flutter but when i send first message it received it successfully the next message make app crush with Reply already submitted error her on this line result.success(txt);
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "demo.gawkat.com/info";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("getMessage")) {
Pusher pusher = new Pusher("faa685e4bb3003eb825c");
pusher.connect();
Channel channel = pusher.subscribe("messages");
channel.bind("new_message", (channelName, eventName, data) -> runOnUiThread(() -> {
Gson gson = new Gson();
Message message = gson.fromJson(data, Message.class);
String txt = message.text;
result.success(txt);
}));
}
});
}
}
Flutter code:
Future<String> _getMessage() async {
String value;
try {
value = await platform.invokeMethod('getMessage');
} catch (e) {
print(e);
}
return value;
}
Error is
FATAL EXCEPTION: main
Process: com.example.flutter_app, PID: 6296
java.lang.IllegalStateException: Reply already submitted
at io.flutter.view.FlutterNativeView$PlatformMessageHandlerImpl$1.reply(FlutterNativeView.java:197)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:204)
at com.example.flutter_app.MainActivity.lambda$null$0(MainActivity.java:40)
at com.example.flutter_app.-$$Lambda$MainActivity$axbDTe2B0rhavWD22s4E8-fuCaQ.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767
I think it is happening after Flutter upgrade > 1.5.4.hotfix.
Anyway, Yes there is a solution (Refer this github issue),
In your Activitybelow onCreate() add this class:
private static class MethodResultWrapper implements MethodChannel.Result {
private MethodChannel.Result methodResult;
private Handler handler;
MethodResultWrapper(MethodChannel.Result result) {
methodResult = result;
handler = new Handler(Looper.getMainLooper());
}
#Override
public void success(final Object result) {
handler.post(
new Runnable() {
#Override
public void run() {
methodResult.success(result);
}
});
}
#Override
public void error(
final String errorCode, final String errorMessage, final Object errorDetails) {
handler.post(
new Runnable() {
#Override
public void run() {
methodResult.error(errorCode, errorMessage, errorDetails);
}
});
}
#Override
public void notImplemented() {
handler.post(
new Runnable() {
#Override
public void run() {
methodResult.notImplemented();
}
});
}
}
Then, instead of using MethodChannel result to setMethodCallHandler argument callback add name as rawResult and then inside that callback, add this line:
MethodChannel.Result result = new MethodResultWrapper(rawResult);
As below:
//......
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
(call, rawResult) -> {
MethodChannel.Result result = new MethodResultWrapper(rawResult);
//.....
I use flags for this problem.
Just make sure that methods of same channels are called simultaneously.
The problem seem to appear then.
If two methods needs to be called simulatenously without any problem define both methods in 2 different channels
var resultMap = Map<String, MethodChannel.Result> = HashMap()
new MethodChannel(getFlutterView(), CHANNEL_1).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("method1")) {
// implement method 1
}
});
new MethodChannel(getFlutterView(), CHANNEL_2).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("method2")) {
resultMap = resultMap + mapOf(CHANNEL_2 to MethodResultWrapper(result) // use this later to return result
// implement method2
result.success(true) // or whatever value
}
});
This reduce the chance of "Reply already submitted" error.
Incase if you are using MethodResultWrapper as #Blasanka answer use flags before result.success
when method is invoked set flag to true
val methodCheckFlag: Boolean = true
then when result need to be returned
if(methodCheckFlag) {
methodCheckFlag = false;
methodWrapperResult?.success(true) // or what ever value to return
}
or use the saved MethodResultWrapper as
if(methodCheckFlag) {
methodCheckFlag = false;
resultMap[CHANNEL_2]?.success(true) // or what ever value to return
}

How to catch unhandled errors in ASP.NET MVC?

I've created a simple MVC project, add one method:
public class HomeController : Controller
{
public async Task<string> Index()
{
var t = Task.Run(() =>
{
Debug.Print("Debug___1");
throw new Exception("Error #1");
Debug.Print("Debug___2");
});
await Task.Delay(5000);
return "ASD";
}
}
Then i run application, get "ASD" output and debug messages:
Debug___1
Exception thrown: 'System.Exception' in WebApplication2.dll
But how can I catch that exception? I've tried creating Application_Error method on global.asas, but it didn't work:
namespace WebApplication2
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_Error(object sender, EventArgs e)
{
Debug.Print("Catched");
}
}
}
At the controller level, you can deal with unhandled exceptions by overriding the OnException method.
Look at this link for a description: https://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine
catch(Exception ex)
{
//create custom error handling method
ErrorLog(ex);
}
Public static void Errorlog(Exception ex)
{
//creates new txt file to view errordetails
string strPath = #"D:\ErrorLog.txt";
File.create(strPath);
using (StreamWriter sw = File.AppendText(strPath))
{
sw.WriteLine("Error Details",+DateTime.Now);
sw.WriteLine("Error Message: " + ex.Message);
sw.WriteLine("Stack Trace: " + ex.StackTrace);
}
}
.NET 4 allows you to define how your task will handle exceptions as shown in the following post : catch exception that is thrown in different thread
So in your example above, you would first define your task
Task<string> task = new Task<string>(Test);
then pass in an exception handler
task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
then finally define an exception handler somewhere
static void ExceptionHandler(Task<string> task)
{
var exception = task.Exception;
//Handle error via ModelState or how you prefer
}
Use the HttpServerUtility.HttpApplication.Server object's method GetLastError.
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
}

Perform Action in MQTT Subscriber

This mqtt subscriber code works fine. I can easily subscribe to messages which are published at broker.hivemq.com with respective topic.
public class AccelerometerSubscriber implements MqttCallback,
IMqttActionListener {
public static void main(String[] args) throws MqttException {
int QUALITY_OF_SERVICE = 2;
MqttClient client=new MqttClient("tcp://broker.hivemq.com:1883",
MqttClient.generateClientId());
client.setCallback( new SimpleMqttCallBack() );
client.connect();
System.out.println("Subscribing ....");
client.subscribe("MQTT Examples"); }
System.out.println("some action"); //------------right here--------------
public void connectionLost(Throwable throwable) {
System.out.println("Connection to MQTT broker lost!"); }
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
System.out.println("Message received:\n\t"+ new String(mqttMessage.getPayload()) );
}
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
// not used in this example
}}
Now I want to perform action only when a message is received. I'm unable to do that.
You have a class (AccelerometerSubscriber) that implements the interface MqttCallback, use an instance of it instead of doing client.setCallback( new SimpleMqttCallBack() );
public class AccelerometerSubscriber implements MqttCallback, IMqttActionListener {
public static void main(String[] args) throws MqttException {
AccelerometerSubscriber as = new AccelerometerSubscriber();
int QUALITY_OF_SERVICE = 2;
MqttClient client = new MqttClient("tcp://broker.hivemq.com:1883", MqttClient.generateClientId());
client.setCallback(as);
client.connect();
System.out.println("Subscribing ....");
client.subscribe("MQTT Examples");
}
#Override
public void connectionLost(Throwable throwable) {
System.out.println("Connection to MQTT broker lost!");
}
#Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
//message is received is here!!!
System.out.println("Message received:\n\t" + new String(mqttMessage.getPayload()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("deliveryComplete");
}
#Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
System.out.println("onFailure");
}
#Override
public void onSuccess(IMqttToken arg0) {
System.out.println("onSuccess");
}
}

Thread.sleep (change image) Java

I have two jlabels with an image.. I try to change the image in a label when the other is clicked.. (such as a game)..
I have a problem..When i write the Thread.sleep the image is not change..See the code:
public class Game extends JFrame{
private JLabel l1,l2;;
private boolean isClicked = false ,isClicked2 = false;
public Game(){
setLayout(new FlowLayout());
l1 = new JLabel(new ImageIcon(getClass().getResource("image1.png")));
add(l1);
l2 = new JLabel(new ImageIcon(getClass().getResource("image1.png")));
add(l2);
l1.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {
if(isClicked2){
l1.setIcon(new ImageIcon(getClass().getResource("image2.png")));
try {
Thread.sleep(1000);
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked2 = false;
isClicked = false;
}catch(InterruptedException ex){}
}
else{
l1.setIcon(new ImageIcon(getClass().getResource("image2.png")));
isClicked = true;
}
}#Override public void mouseEntered(MouseEvent e){}#Override public void mouseExited(MouseEvent e){}
});
l2.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {
if(isClicked){
try {
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
Thread.sleep(1000);
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked = false;
isClicked2 = false;
}catch(InterruptedException ex){}
}
else{
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
isClicked2 = true;
}
}#Override public void mouseEntered(MouseEvent e){}#Override public void mouseExited(MouseEvent e){}
});
}
public static void main(String[] args) {
Game g = new Game();
g.setTitle("Fint the same");
g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g.pack();
g.setVisible(true);
}
}
Run it and first click the fisrt label.. After click the second label and the first will change image in 1 second but the seconf label NEVER!!
The changing of the images has to be done on the event thread (the thread used to process graphics events). Therefore setting the image will queue an appropriate event to be processed after your method returns. At that time though, the image has already changed back, because sleep()ing on the event thread doesn't allow any other events to be processed.
As dashrb said, don't sleep() the main thread, but schedule the flip back in a Timer:
if (isClicked) {
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked = false;
isClicked2 = false;
}
}).start();
} catch (final Exception ex) {
ex.printStackTrace();
}
} else {
...
You should not sleep() in these methods--they are invoked from the "event dispatch" thread, which handles all drawing events. If you're sleeping, then the thread can't be repainting your labels.
Rather than sleeping, change your image, then create a javax.swing.Timer task which will fire 1-second-from-now to change the images again as desired. The sample from koljaTM above uses a java.util.Timer, which runs in the "wrong" thread. This is his code, modified to use a SWING timer:
if (isClicked) {
try {
l2.setIcon(new ImageIcon(getClass().getResource("image2.png")));
javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
l2.setIcon(new ImageIcon(getClass().getResource("image1.png")));
System.out.println("image2 gone");
l1.setIcon(new ImageIcon(getClass().getResource("image1.png")));
isClicked = false;
isClicked2 = false;
}
});
timer.setRepeats(false);
timer.start();
} catch (final Exception ex) {
ex.printStackTrace();
}
} else {
...

Runtime Exception in Send Message in BlackBerry

I am getting RunTime Exception when I am Running this code..Please Go Through it and Help me if you have any idea. Thanks..
private void sendSMS(String phone, String message) throws IOException
{
// TODO Auto-generated method stub
Dialog.alert("Hello..In Send SMS Function");
System.out.println("in send sms function");
MessageConnection conn =
(MessageConnection)Connector.open("sms://+919099956325");
TextMessage tmsg = (TextMessage) conn.newMessage(MessageConnection.TEXT_MESSAGE);
tmsg.setAddress("sms://+919429441335");
tmsg.setPayloadText("HIIiii");
System.out.println("Text message is>>"+tmsg);
conn.send(tmsg);
}
instead of
System.out.println("Text message is>>"+tmsg);
use
System.out.println("Text message is>>"+tmsg.getPayloadText());
Also Connector.open is a blocking operation and should not be called from a main event thread.
You have Dialog.alert which will only work on a event thread. Do this
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("Hello..In Send SMS Function");
}
});
Try this code . this starts a new thread and calls sendsms method
new Thread(new Runnable() {
public void run() {
try {
sendSMS("123456789","message");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
private void sendSMS(String phone, String message) throws IOException
{
try {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("Hello..In Send SMS Function");
}
});
System.out.println("in send sms function");
MessageConnection conn =
(MessageConnection)Connector.open("sms://+919099956325");
TextMessage tmsg = (TextMessage) conn.newMessage(MessageConnection.TEXT_MESSAGE);
tmsg.setAddress("sms://+919429441335");
tmsg.setPayloadText("HIIiii");
System.out.println("Text message is>>"+tmsg.getPayloadText());
conn.send(tmsg);
} catch (Exception e) {
System.out.println("Exception is >>"+e.toString());
}
}

Resources