I have custom exception class bellow
class Failure implements Exception {
String cause;
Failure(this.cause);
}
and have bellow class to call login request
class Http {
void login(String userName, String password) async {
var headers = {
'Content-Type': 'application/x-www-form-urlencoded',
};
var data = {
'client_id': '..',
'client_secret': '...',
'grant_type': 'password',
'scope': '...',
'username': userName,
'password': password,
};
var url = Uri.parse('http://x.com/connect/token');
var res = await http.post(url, headers: headers, body: data);
if (res.statusCode != 200) {
throw 'http.post error: statusCode= ${res.statusCode}';
}
}
}
The problem is how can I handle errors properly on the presentation layer
class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key);
static const String routeName = '/login';
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _userName = TextEditingController();
final TextEditingController _password = TextEditingController();
late bool _obscurePassword;
@override
void initState() {
super.initState();
_obscurePassword = true;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: _userName,
decoration: const InputDecoration(
icon: Icon(Icons.person), label: Text('username')),
validator: (value) {
if (value == null || value.isEmpty) {
return 'not empty';
}
return null;
},
),
const SizedBox(
height: 8,
),
TextFormField(
controller: _password,
obscureText: _obscurePassword,
decoration: InputDecoration(
icon: const Icon(Icons.password),
label: const Text('password'),
suffixIcon: IconButton(
icon: Icon(
_obscurePassword
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_obscurePassword = !_obscurePassword;
});
},
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'not empty';
}
return null;
},
),
const SizedBox(
height: 12,
),
ElevatedButton(
onPressed: () {
onLoginSubmit(context);
},
child: const Text('login'),
),
],
),
),
),
);
}
//-----> how handle errors and show on UI , I get Error: http.post error: statusCode= 400 on console right now
void onLoginSubmit(BuildContext context) async {
Http http = Http();
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState!.validate()) {
//save token
try {
http.login(_userName.text, _password.text);
} catch (e, s) {
print(s);
}
}
}
}
I get Error: http.post error: statusCode= 400
in console right now, whats the problem?
and If there is a brief article to handle HTTP request secure and properly please provide it in the comments or answer bellow
CodePudding user response:
Use Snackbar if you have scaffold
try {
http.login(_userName.text, _password.text);
} catch (e, s) {
const snackBar = SnackBar(
content: Text('Error!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
Or any other toast package
CodePudding user response:
Use await keyword to process Future requests such as an HTTP post request
First change void login(...)
in your HTTP class to Future<void> login(...)
Then use await keyword when you want to call this method for example in your UI
void onLoginSubmit(BuildContext context) async {
Http http = Http();
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState!.validate()) {
//save token
try {
await http.login(_userName.text, _password.text);
} catch (e, s) {
debugPrint(s);
}
}
}
}
And use debugPrint
from dart:foundation
library instead of print