Unable to catch Google cloud storage exception - flutter

I have a function in my flutter app to download a file from google cloud and store it locally. This function works for existing files, but when I try to download a non existent file, it fails to catch the 'file not found' exception. I'm obviously doing something wrong, but I can't figure it out!
bool downloadFile({required String localFile, required String remoteFile}) {
try {
final storageRef = FirebaseStorage.instance.ref();
final remoteFileRef = storageRef.child(remoteFile);
final file = File(localFile);
final downloadTask = remoteFileRef.writeToFile(file);
downloadTask.snapshotEvents.listen((taskSnapshot) {
switch (taskSnapshot.state) {
case TaskState.running:
print('TaskState.running');
break;
case TaskState.paused:
print('TaskState.paused');
break;
case TaskState.success:
print('TaskState.success');
break;
case TaskState.canceled:
print('TaskState.canceled');
break;
case TaskState.error:
print('TaskState.error');
break;
}
});
//} on firebase_core.FirebaseException catch (error) {
} catch (e) {
print("########### got ex");
return false;
}
return true;
}

Related

Unhandled Exception: Concurrent modification during iteration: Instance(length:2) of '_GrowableList'

I am using Geofire in firebase to get the location of two different users. As long as I have just 1 user it works fine but when there are more than two users online then I get the above error
Future<void> initGeoFireListener() async {
var driverLocation =
FirebaseDatabase.instance.ref().child("availableDrivers").path;
try {
Geofire.initialize(driverLocation).catchError((onError) {
print("Driver $onError");
});
Geofire.queryAtLocation(
position.latitude, position.longitude, 50)! //10 km
.listen((map) {
print("drivers map: $map");
if (map != null) {
print("Nearby Drivers: $map");
var callBack = map['callBack'];
switch (callBack) {
case Geofire.onKeyEntered:
NearByAvailableDrivers nearByAvailableDrivers =
NearByAvailableDrivers(
map['key'], map['latitude'], map['longitude']);
GeoFireAssistant.nearByAvailableDriversList
.add(nearByAvailableDrivers);
updateAvailableDriversOnMap();
// }
break;
case Geofire.onKeyExited: //when any driver is offline
GeoFireAssistant.removeDriverFromList(map['key']);
updateAvailableDriversOnMap();
// } else {
print("xxxx onKeyExited ${availableDrivers.length}");
// }
break;
case Geofire.onKeyMoved: //as driver position change
NearByAvailableDrivers nearByAvailableDrivers =
NearByAvailableDrivers(
map['key'], map['latitude'], map['longitude']);
GeoFireAssistant.updateDriverNearByLocation(
nearByAvailableDrivers);
updateAvailableDriversOnMap();
break;
case Geofire.onGeoQueryReady:
updateAvailableDriversOnMap();
// } else {
print("xxxx onGeoqueryready ${availableDrivers.length}");
// }
break;
}
} else {
print("Drivers Null");
}
// setState(() {});
}).onError((error) {
print("Drivers error $error");
});
} on PlatformException {
print("Drivers : No platformException response");
}
}
void updateAvailableDriversOnMap() async {
for (NearByAvailableDrivers driver
in GeoFireAssistant.nearByAvailableDriversList) { driverKey = driver.key; } //error triggered here
class NearByAvailableDrivers {
String? key;
double? latitude;
double? longitude;
NearByAvailableDrivers(this.key, this.latitude, this.longitude);
}
class GeoFireAssistant {
static List<NearByAvailableDrivers> nearByAvailableDriversList = []; //error
static void removeDriverFromList(String? key) {
int index =
nearByAvailableDriversList.indexWhere((element) => element.key == key);
nearByAvailableDriversList.removeAt(index);
}
static void updateDriverNearByLocation(NearByAvailableDrivers driver) {
int index = nearByAvailableDriversList
.indexWhere((element) => element.key == driver.key);
nearByAvailableDriversList[index].latitude = driver.latitude;
nearByAvailableDriversList[index].longitude = driver.longitude;
}
}
The error
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Concurrent modification during iteration: Instance(length:2) of '_GrowableList'
I do understand I am using For loop in NearByAvailableDrivers and modifying it at the same time which could be the source of the error but I am unable to fix it.

Amplify DataStore: How to know when sync is finished?

How can we know that DataStore has finished the sync?
When doing the first await DataStore.query(MyEntity) after the user logged in, DataStore is returning right away and not waiting for the data to be synced with the cloud.
I want to wait for the sync to be completed and put a loading when the data isn't synced yet.
make your model class observable so that it can check for data in realtime
Amplify.DataStore.observeQuery(MyEntity.classType).listen((event) {
if (event.isSynced) {//boolean value
print("Synced Successfully!");
// even you can get synced data here also
List< MyEntity> items = event.items;
} else {
//Show ProgressBar Here
print("Fetching Data From Cloud");
}
});
You can listen to events on the datastore channel with Amplify.Hub.listen.
details:
subscription = Amplify.Hub.listen([HubChannel.DataStore], (dynamic hubEvent) async {
switch (hubEvent.eventName) {
case 'networkStatus':
_amplifyIsUp.value = hubEvent.payload.active;
break;
case 'subscriptionsEstablished':
_amplifyMessage.value = 'Starting to sync from cloud...';
break;
case 'syncQueriesStarted':
_amplifyIsSyncing.value = true;
_amplifyMessage.value = 'Syncing...';
break;
case 'modelSynced':
ModelSyncedEvent mse = hubEvent.payload;
_amplifyMessage.value = '${mse.modelName} has been sync\'d from cloud...';
break;
case 'syncQueriesReady':
_amplifyMessage.value = 'Done!';
_amplifyIsSyncing.value = false;
///do your bits here
onSyncsReady.call();
break;
case 'ready':
_amplifyIsSyncing.value = false;
break;
case 'subscriptionDataProcessed':
SubscriptionDataProcessedEvent sdpe = hubEvent.payload;
_amplifyMessage.value = 'Syncing ${sdpe.element.model.classType.modelName()}...';
if (sdpe.element.model is DeviceStatus) {
DeviceStatus ds = sdpe.element.model as DeviceStatus;
if (ds.clientID == _clientService.client.id && ds.status == Status.REQUESTSTATUS) {
_statusService.performHeartbeat();
}
}
break;
case 'outboxMutationEnqueued':
_amplifyIsSyncing.value = true;
_amplifyHasDirt.value = true;
break;
case 'outboxMutationProcessed':
OutboxMutationEvent ome = hubEvent.payload;
_amplifyIsSyncing.value = false;
break;
case 'outboxStatus':
OutboxStatusEvent ose = hubEvent.payload;
if (ose.isEmpty) {
_amplifyIsSyncing.value = false;
_amplifyHasDirt.value = false;
} else {
_amplifyHasDirt.value = true;
}
break;
}
});
boop

Flutter BLoC:Global exception handler for mapEventToState

I use felangel's bloc library. I fetch data by using a repository in mapEventToState method .If the repository throws an exception, I want to catch it on a global exception handler.
#override
Stream<MyState> mapEventToState(Event event) async* {
if (event is MyEvent) {
try {
var data = await repository.fetchData();
yield MyState(data);
} catch (e) {
//There may be many exceptions
}
}
}
Is there any way catch exceptions without try-catch blocks and what is best practice?
You could write a util for managing errors. I wrote something for this. It could be an idea for you.
static String handleError(Error error) {
String errorDescription = "";
if (/*error is SomethingError*/) {
switch (error.type) {
case ErrorType.CANCEL:
errorDescription = "ErrorType.CANCEL";
break;
case ErrorType.CONNECT_TIMEOUT:
errorDescription = "ErrorType.CONNECT_TIMEOUT";
break;
case ErrorType.DEFAULT:
errorDescription = "ErrorType.DEFAULT";
break;
case ErrorType.RECEIVE_TIMEOUT:
errorDescription = "ErrorType.RECEIVE_TIMEOUT";
break;
case ErrorType.RESPONSE:
switch (error.response.toString()) {
case "usernamePasswordFail":
errorDescription = "usernamePasswordFail";
break;
default:
errorDescription = "errorDescription";
}, ${error.response.data ?? ''}";
break;
}
break;
case ErrorType.SEND_TIMEOUT:
errorDescription = "ErrorType.SEND_TIMEOUT";
break;
}
} else {
errorDescription = "somethingElseError";
}
return errorDescription;
}

Cancel Or Exit from PromptDialog.Choice Flow in Microsoft Bot Framework

i have a Prompt with 4 options, the last option is user can quit the Prompt,
i want to implement some code so that the bot exit the Prompt
Image
PromptDialog.Choice(context, this.OnOptionSelected, new List<string>() { FlightsOption, HotelsOption, TrainOption, GobackOption }, "Sure..! Tell me what booking would like to make..?", "Not a valid option", 3);
in above image i had implemented quit option on which if user selects quit it goes to Switch case of quit.
i had also tried context.quit but it throws error
private async Task OnOptionSelected(IDialogContext context, IAwaitable<string> result)
{
try
{
string optionSelected = await result;
switch (optionSelected)
{
case FlightsOption:
context.Call(new FlightDialog(), this.ResumeAfterOptionDialog);
break;
case HotelsOption:
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog);
break;
case TrainOption:
context.Call(new TrainDialog(), this.ResumeAfterOptionDialog);
break;
case GobackOption:
//want some code here to quit the form
break;
}
}
First of all this is not a Form Flow. This is prompt.
Now You can do something like, either you exit the dialog from the stack like this
try
{
string optionSelected = await result;
switch (optionSelected)
{
case FlightsOption:
context.Call(new FlightDialog(), this.ResumeAfterOptionDialog);
break;
case HotelsOption:
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog);
break;
case TrainOption:
context.Call(new TrainDialog(), this.ResumeAfterOptionDialog);
break;
case GobackOption:
context.Done<object>(null);
break;
}
}
Or,
You can tell something and then wait for other message in the same dialog like this
try
{
string optionSelected = await result;
switch (optionSelected)
{
case FlightsOption:
context.Call(new FlightDialog(), this.ResumeAfterOptionDialog);
break;
case HotelsOption:
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog);
break;
case TrainOption:
context.Call(new TrainDialog(), this.ResumeAfterOptionDialog);
break;
case GobackOption:
await context.PostAsync("Ok, you came back. Now tell something new.");
context.Wait(MessageReceivedAsync);
break;
}
}
And the next message will go here
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
context.Wait(MessageReceivedAsync);
}

Any other option to deploy in jboss server ither than hot deployment?

I want to know what are the methods to deploy in jboss server other than hot deployment.
Get the client and the builder to build plans:
ModelControllerClient client = ModelControllerClient.Factory.create(host, port);
ServerDeploymentManager manager = ServerDeploymentManager.Factory.create(client);
DeploymentPlanBuilder builder = manager.newDeploymentPlan();
And the method to execute any kind of operation (here some ones are implemented):
public DeployementActionStatus execute(Type deploy) throws IOException
{
List<Throwable> errors = new LinkedList<Throwable>();
DeployementActionStatus status = DeployementActionStatus.SUCCESS;
switch (deploy)
{
case DEPLOY:
if (archive != null)
{
plan = builder.add(archive).deploy(archive.getName()).build();
}
else
{
return DeployementActionStatus.FAILURE;
}
break;
case REDEPLOY:
{
if (archive != null)
{
plan = builder.redeploy(archive.getName()).build();
}
else
{
return DeployementActionStatus.FAILURE;
}
break;
}
case UNDEPLOY:
{
plan = builder.undeploy(getApplicationName()).build();
break;
}
case REMOVE:
{
plan = builder.remove(getApplicationName()).build();
break;
}
default:
plan = null;
break;
}
if (plan == null)
{
throw new IllegalStateException("Invalid type: " + deploy);
}
if (plan.getDeploymentActions().size() > 0)
{
try
{
final ServerDeploymentPlanResult planResult = manager.execute(plan).get();
// Check the results
for (DeploymentAction action : plan.getDeploymentActions())
{
final ServerDeploymentActionResult actionResult = planResult.getDeploymentActionResult(action
.getId());
final ServerUpdateActionResult.Result result = actionResult.getResult();
switch (result)
{
case FAILED:
case NOT_EXECUTED:
case ROLLED_BACK:
{
log.error(actionResult.getDeploymentException());
if (actionResult.getDeploymentException().getMessage() != null
&& actionResult.getDeploymentException().getMessage().contains("Duplicate"))
{
status = DeployementActionStatus.FAILURE_ALREADY_DEPLOYED;
}
else
{
status = DeployementActionStatus.FAILURE;
}
break;
}
case CONFIGURATION_MODIFIED_REQUIRES_RESTART:
// Should show warning
break;
default:
break;
}
}
}
catch (InterruptedException e)
{
errors.add(e);
status = DeployementActionStatus.FAILURE;
}
catch (ExecutionException e)
{
errors.add(e);
status = DeployementActionStatus.FAILURE;
}
catch (Exception e)
{
if (e instanceof RuntimeException)
{
status = DeployementActionStatus.CONNECTION_TO_SERVER_FAILED;
}
}
}
return status;
}
Deploying is considered hot only when JBoss is running. If you don't want hot deployment you can turn off deployment scanner [1] or stop JBoss and deploy the artifact.
[1] https://community.jboss.org/wiki/ConfiguringTheDeploymentScannerInConfjbossSystemxml