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

Exception in converter function is not shown anywhere. #85

Closed
sidlatau opened this issue Oct 2, 2018 · 6 comments
Closed

Exception in converter function is not shown anywhere. #85

sidlatau opened this issue Oct 2, 2018 · 6 comments

Comments

@sidlatau
Copy link

sidlatau commented Oct 2, 2018

If exception is thrown in converter function it is not shown anywhere. Check an example app - exception is thrown when counter is odd number. App just works, but it shows only even numbers. It is difficult to catch such bugs. Exception is not visible anywhere - maybe at least it could be logged to console?

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return StoreProvider<AppState>(
      store: createStore(),
      child: StoreConnector<AppState, HomeViewModel>(
        distinct: true,
        converter: (store) => HomeViewModel.fromStore(store),
        builder: (_, viewModel) => Scaffold(
              appBar: AppBar(
                title: Text(title),
              ),
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(
                      'You have pushed the button this many times:',
                    ),
                    Text(
                      '${viewModel.counter}',
                      style: Theme.of(context).textTheme.display1,
                    ),
                  ],
                ),
              ),
              floatingActionButton: FloatingActionButton(
                onPressed: viewModel.incrementCounter,
                tooltip: 'Increment',
                child: Icon(Icons.add),
              ),
            ),
      ),
    );
  }
}

class AppState {
  final int counter;

  AppState(this.counter);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is AppState &&
          runtimeType == other.runtimeType &&
          counter == other.counter;

  @override
  int get hashCode => counter.hashCode;
}

Store<AppState> createStore() {
  return Store(appReducer, initialState: AppState(0));
}

AppState appReducer(AppState state, dynamic action) {
  if (action is IncreaseCounterAction) {
    return AppState(state.counter + 1);
  }
  return state;
}

class IncreaseCounterAction {}

class HomeViewModel {
  factory HomeViewModel.fromStore(Store<AppState> store) {
    if (store.state.counter.isOdd) {
      throw Exception('Error!');
    }

    return HomeViewModel(
        counter: store.state.counter,
        incrementCounter: () {
          store.dispatch(IncreaseCounterAction());
        });
  }

  Function incrementCounter;

  int counter;

  HomeViewModel({@required this.incrementCounter, @required this.counter});

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is HomeViewModel &&
          runtimeType == other.runtimeType &&
          counter == other.counter;

  @override
  int get hashCode => counter.hashCode;
}
@brianegan
Copy link
Owner

Hey there -- hrm, good call. I'll check out how I can expose these errors

@rostyslavroshak
Copy link

What if we start with adding assert to stream builder, something like these:

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<ViewModel>(
        stream: stream,
        builder: (context, snapshot) {
          assert(snapshot.error == null, 'snapshot has error ${snapshot.error}'); //at least you will see red flutter error in debug builds.
          return widget.builder(
            context,
            snapshot.hasData ? snapshot.data : latestValue,
          );
        });
  }

@arteminthesky
Copy link

arteminthesky commented Feb 12, 2020

I just ran into a similar problem, only I used onWillChange. If there is any error inside the callback, it is impossible to see it, moreover, the new state will not apply to the builder.

@nashfive
Copy link

Hey there! I ran into the same issue today too, and I lost almost a day trying to figure this out. Any idea how we can avoid those error to be swallowed ?

@brianegan
Copy link
Owner

Hey all -- thanks for the feedback and apologies on being slow on this one. I think since I generally test converter functions I didn't run into this as much, but it's an important topic.

I've got a branch going to help alleviate these issues. Could you please check out the following PR and tell me if it would help?

#170

@brianegan
Copy link
Owner

Fixed

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

No branches or pull requests

5 participants