how to use the object inside catch - dart

How to I convert the object inside catch?
class Sample {
final String? errorCode;
Sample({this.errorCode});
}
void main() {
var sample = Sample(errorCode: 'sample');
try {
throw sample;
} catch(err) {
print(err); // I would like to get the errorCode e.g. err.errorcode
}
}

Either make sure to only catch a Sample, then err will have that type:
} on Sample catch (error) {
print(error.errorCode);
}
or check/cast inside the catch block:
} catch (error) {
if (error is Sample) print(error.errorCode);
print((error as Sample).errorCode);
}
The first approach is safer if you only expect to catch a Sample.
The is-check can be used if you want to catch other things too, but treat Sample specially.
The as should not be used outside of quick-and-dirty code, because it can throw if you catch something other than a Sample, and you don't want your error handling to throw!

Related

exception occurs when iterating through futures

Can someone please explain to me what this piece of code does and how it can enter on the second catch clause, inside finally (without entering the first catch) and log this message "log.error("error while running closure", ee)" ?
try {
batches.each { batch -> futures << executorService.submit(['call':runClosure.curry(batch)] as Callable) }
} catch (Exception e) {
log.error("error: ", e)
} finally {
futures.each {
try {
it.get()
} catch (Exception ee) {
log.error("error while running closure", ee)
}
}
}
I have this piece of code that calls the method processBatch:
def runClosure = { batch ->
processBatch(batch)
}

Connection and unknown errors in FlutterFire Messaging (iOS Only)

I implemented FlutterFire Messaging with the subscribeToTopic method, as the snippet below:
final _topics = ['topicName'];
Future<void> subscribeTopics() async {
for (final topic in _topics) {
await FirebaseMessaging.instance.subscribeToTopic(topic);
}
}
Future<void> unsubscribeTopics() async {
for (final topic in _topics) {
await FirebaseMessaging.instance.unsubscribeFromTopic(topic);
}
}
And everything is fine in debug mode, but in my Crashlytics I'm receiving some reports about it (iOS only):
[firebase_messaging/unknown] The request timed out
[firebase_messaging/unknown] An unknown error has occurred
[firebase_messaging/unknown] A data connection is not currently allowed
[firebase_messaging/unknown] The Internet connection appears to be offline
All the errors appears to be about internet connection, so my question is: "Should I validate the user connection before use FCM or the lib is ready to deal with it but only in Android?"
Crashlytics Stacktrace
Non-fatal Exception: FlutterError
0 ??? 0x0 MethodChannelFirebaseMessaging.subscribeToTopic + 368 (method_channel_messaging.dart:368)
1 ??? 0x0 Messaging.subscribeTopics + 40 (messaging.dart:40)
2 ??? 0x0 Messaging.observeMessaging + 22 (messaging.dart:22)
It's a general error so you shouldn't worry about it. When the internet connection restores the method will hopefully restart itself. You should also consider the case that It might generate an error while the app is in the background.
You can use try catch block to avoid these messages in your crashlytics dashboard.
final _topics = ['topicName'];
Future<void> subscribeTopics() async {
try {
for (final topic in _topics) {
await FirebaseMessaging.instance.subscribeToTopic(topic);
}
} on FirebaseException {
// do nothing
}
}
Future<void> unsubscribeTopics() async {
try {
for (final topic in _topics) {
await FirebaseMessaging.instance.unsubscribeFromTopic(topic);
}
} on FirebaseException {
// do nothing
}
}
Note It will also ignore all other error messages too. In that case
You can handle it otherwise
final _topics = ['topicName'];
Future<void> subscribeTopics() async {
try {
for (final topic in _topics) {
await FirebaseMessaging.instance.subscribeToTopic(topic);
}
} on FirebaseException catch (e) {
if (e.code == 'unknown') {
// do nothing
} else {
// do something
}
}
}
Future<void> unsubscribeTopics() async {
try {
for (final topic in _topics) {
await FirebaseMessaging.instance.unsubscribeFromTopic(topic);
}
} on FirebaseException catch (e) {
if (e.code == 'unknown') {
// do nothing
} else {
// do something
}
}
}

Catch statement does not catch thrown error in debug mode in an async function

I do not know why catch statement does not catch thrown error when I debug the app.
This is the main function:
void main() async {
final initialState = await persistor.load();
bool logged = false;
if (initialState.isLoggedIn) {
logged = await initialState.silentlyLogin(); // <---- FUNCTION THAT THROWS ERROR
}
if (!logged) {
initialState.logout();
}
}
This is the silentlyLogin function of my State class:
Future<bool> silentlyLogin() async {
try {
await globals.googleSignIn.signInSilently();
return true;
} catch (e) {
return false;
}
}
In debug the googleSignIn.signInSilently function thrown an error, in this part of code:
#override
dynamic decodeEnvelope(ByteData envelope) {
// First byte is zero in success case, and non-zero otherwise.
if (envelope.lengthInBytes == 0)
throw const FormatException('Expected envelope, got nothing');
final ReadBuffer buffer = ReadBuffer(envelope);
if (buffer.getUint8() == 0)
return messageCodec.readValue(buffer);
final dynamic errorCode = messageCodec.readValue(buffer);
final dynamic errorMessage = messageCodec.readValue(buffer);
final dynamic errorDetails = messageCodec.readValue(buffer);
if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining)
throw PlatformException(code: errorCode, message: errorMessage, details: errorDetails); // <------ HERE IS THE ERROR
else
throw const FormatException('Invalid envelope');
}
In the debug mode, android studio blocks the app in the throw PlatformException line, but my catch statement is never catched, so my function always returns true.
While my catch statement is never catched.
The exception is probably thrown in native code and not passed to Dart at all. Dart can't catch Java or ObjectivC/Swift exceptions. The plugin would need to catch it in Java, send a message to Dart and in Dart an artificial exception would need to be thrown.
See also
https://github.com/flutter/flutter/issues/17677
https://github.com/flutter/flutter/issues/19748
https://github.com/flutter/flutter/issues/28430

How to pass message to isolate and handle error

I am trying to use dart isolate library to improve my application performance.
Look at following code:
import 'dart:isolate';
import 'package:dbcrypt/dbcrypt.dart';
main() {
var pwConPort = new ReceivePort();
pwConPort.listen((data) {
print(data);
pwConPort.close();
}, onError: (err) {
print(err);
});
Isolate.spawn(generatePasswordConcurrency, pwConPort.sendPort);
}
void generatePasswordConcurrency(SendPort sendPort) {
sendPort.send(_generateHashPassword('Passsowr1222!'));
}
String _generateHashPassword(String password) {
var regex = new RegExp(r'^.*(?=.{7,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).*$');
if (!regex.hasMatch(password)) {
throw new StateError('Errors');
}
return new DBCrypt().hashpw(password, new DBCrypt().gensalt());
}
Everything works fine but i can only pass a static password, or better to say, i don't know, how to pass something dynamically. Here you can see, password is hardcoded, but i want to pass a variable for example.
void generatePasswordConcurrency(SendPort sendPort) {
sendPort.send(_generateHashPassword('Passsowr1222!'));
}
If the method _generateHashPassword will throw an error, how can I handling this error? I try to catch the error on listen method from ReceivePort
pwConPort.listen((data) {
print(data);
pwConPort.close();
}, onError: (err) {
print(err);
});
but still got unhandling exceptions message.
Observatory listening on http://127.0.0.1:51433
in ShutdownIsolate: Unhandled exception:
Bad state: Errors
#0 _generateHashPassword (file:///D:/Dart/samples/bin/isolate_error.dart:26:9)
#1 generatePasswordConcurrency (file:///D:/Dart/samples/bin/isolate_error.dart:19:40)
#2 _startIsolate.isolateStartHandler (dart:isolate-patch/isolate_patch.dart:221)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:124)
Conclusion my question:
How can I pass a variable to called method on isolate?
How can I handling error on isolate?
First of all,
Isolate are not thread, they are independant process more like a fork() than a thread
dartApi: Isolate
Concurrent programming using isolates:
independent workers that are similar to threads but don't share memory, communicating only via
messages.
So, you can't access to the same variable than your parent process. It's a choice made by the dart team, because it's a mechanism usable when you compile your dart code in js. So it need to be possible in JS
How can I pass a variable to called method on isolate?
To do this, you need to see ReceivePort() like a unidirectionnal way of communication, so to pass variable in two way, you need two.
So on you main process:
pwConPort.listen((data) {
if (isolateSendPort == null && data is SendPort) {
isolateSendPort = data; // Receive the communication object of the isolate
isolateSendPort.send("Passsowr1222!");
} else {
print("Generated password: ${data}");
pwConPort.close();
}
}, onError: (err) {
print("SendPortError: ${err}");
});
});
In you isolate entry point :
sendPort.send(isolateConPort.sendPort);
isolateConPort.listen((data) {
// code ....
});
Note: be careful of what message you send. message send between one process and another need to respect some rules
DartApi: SendPort
The content of message can be: primitive values (null, num, bool,
double, String), instances of SendPort, and lists and maps whose
elements are any of these. List and maps are also allowed to be
cyclic.
How can I handling error on isolate?
Isolate get one method to listen throw error send by the isolate : addErrorListner
That is a useful function.
BUT ! this method is not implement in every plate-forme, so you need to do this in a others.
The way i chose is to send 2 SendPort in the entry point function :
One for the communication
One for the error.
So the spawn function looks like :
Isolate.spawn(generatePasswordConcurrency, [pwConPort.sendPort, errorPort.sendPort])
and the generatePasswordConcurrency :
void generatePasswordConcurrency(List<SendPort> commList) {
var sendPort = commList[0];
var errorPort = commList[1];
var isolateConPort = new ReceivePort();
sendPort.send(isolateConPort.sendPort);
isolateConPort.listen((data) {
try {
sendPort.send(_generateHashPassword(data));
} catch (e) {
errorPort.send("error: ${e.toString()}");
}
});
}
Here the full code :
import 'dart:isolate';
import 'package:dbcrypt/dbcrypt.dart';
main() {
var pwConPort = new ReceivePort();
var errorPort = new ReceivePort();
SendPort isolateSendPort = null;
Isolate.spawn(generatePasswordConcurrency, [pwConPort.sendPort, errorPort.sendPort])
.then((Isolate pcs) {
errorPort.listen((err) {
print("Error: ${err}");
pwConPort.close();
errorPort.close();
});
print(pcs);
pwConPort.listen((data) {
if (isolateSendPort == null && data is SendPort) {
isolateSendPort = data;
isolateSendPort.send("Passsowr1222!");
} else {
print("Generated password: ${data}");
pwConPort.close();
errorPort.close();
//pcs.kill();
}
}, onError: (err) {
print("SendPortError: ${err}");
});
});
}
void generatePasswordConcurrency(List<SendPort> commList) {
var sendPort = commList[0];
var errorPort = commList[1];
var isolateConPort = new ReceivePort();
sendPort.send(isolateConPort.sendPort);
isolateConPort.listen((data) {
try {
sendPort.send(_generateHashPassword(data));
} catch (e) {
errorPort.send("error: ${e.toString()}");
}
});
}
String _generateHashPassword(String password) {
var regex = new RegExp(r'^.*(?=.{7,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).*$');
if (!regex.hasMatch(password)) {
throw new StateError('Errors');
}
return new DBCrypt().hashpw(password, new DBCrypt().gensalt());
}

Loopj Post request with body

Dear all i am using Loopj and really like it. It makes my life easier. Now I want post json in the body of the post request.kindly check it what i m doing wrong my code is below.
params.put("SaleOrderItems", mJsonArrayOfObject.toString());
params.put("CustomerReferenceNumber", "asdf");
// /*mSaleOrder.getmCustomerReferenceNo()*/);
params.put("RecordType", "HOS");
params.put("DeliveryDate", "2012-12-28T12:04:27.3553985+01:00"); // mSaleOrder.getmDeliveryDate());
params.put("SellToCustomerNumber", "user");
Then i call like this.
mAsyncHttpClient.post(WEBCONSTANTS.ORDER_SERVICE_SAVE_ORDER, mParams,
new AsyncHttpResponseHandler(){};
I got this error
{"Message":"No HTTP resource was found that matches the request URI}
Kindly tell me how to send json array of objects in the body of the post request using LoopJ.
best regards,
I think this is what you're looking for:
String url = "<your site url>";
JSONObject jdata = new JSONObject();
try {
jdata.put("key1", val1);
jdata.put("key2", val2);
} catch (Exception ex) {
// json exception
}
StringEntity entity;
try {
entity = new StringEntity(jdata.toString());
client.post(getBaseContext(), url, entity, "application/json", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
JSONObject res;
try {
res = new JSONObject(response);
Log.d("debug", res.getString("some_key")); // this is how you get a value out
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

Resources