I recently stumbled across the following Dart code:
void doSomething(String url, String method) {
HttpRequest request = new HttpRequest();
request.open(method, url);
request.onLoad.listen((event) {
if(request.status < 400) {
try {
String json = request.responseText;
} catch(e) {
print("Error!");
}
} else {
print("Error! (400+)");
}
});
request.setRequestHeader("Accept", ApplicationJSON);
}
I'm wondering what the e variable is in the catch clause:
catch(e) {
...
}
Obviously its some sort of exception, but (1) why do we not need to specify its type, and (2) what could I add in there to specify its concrete type? For instance, how could I handle multiple types of possible exceptions in a similar way to catchError(someHandler, test: (e) => e is SomeException)?
Dart is an optional typed language. So the type of e is not required.
you have to use the following syntax to catch only SomeException :
try {
// ...
} on SomeException catch(e) {
//Handle exception of type SomeException
} catch(e) {
//Handle all other exceptions
}
See catch section of Dart: Up and Running.
Finally catch can accept 2 parameters ( catch(e, s) ) where the second parameter is the StackTrace.
Related
I'm checking for a token in the boot() method and catching Invalid Tokens. How can I return some response in the case of an invalid token?
Here's my code:
public function boot(Authenticator $authenticator)
{
Auth::viaRequest('auth-token', function ($request) use ($authenticator) {
$bearerToken = $request->bearerToken();
if ($bearerToken) {
try {
return $authenticator->getUser($bearerToken);
} catch (InvalidTokenException $exeception) {
return response()->json(['token_invalid'], 400);
}
}
});
}
And it pips me the error:
Method Illuminate\Http\JsonResponse::getAuthIdentifier does not exist.
From the docs:
The second argument passed to the method should be a Closure that receives the incoming HTTP request and returns a user instance or, if authentication fails, null
So instead of returning a response object, return null:
if ($bearerToken) {
try {
return $authenticator->getUser($bearerToken);
} catch (InvalidTokenException $exeception) {
return null;
}
}
Im coming from a Java background where I use the throws keyword to lead an exception to the method calling another method. How can I do that I dart?
Method called:
void _updateCurrentUserEmail() async {
await FirebaseAuth.instance
.currentUser()
.then((FirebaseUser user) {
_email = user.email;
});
}
How it is called:
try {
_updateCurrentUserEmail();
} on Exception {
return errorScreen("No User Signed In!", barActions);
}
But it seems like the Exception is not caught, because I still get a NoSuchMethodException and the errorScreen is not shown.
While you correctly used try/catch, the exception is coming from an async function that you did not await.
try/catch only catch exceptions thrown within that block. But since you wrote:
try {
doSomethingAsyncThatWillTrowLater();
} catch (e) {
}
Then the exception thrown by the async method is thrown outside of the body of try (as try finished before the async function did), and therefore not caught.
Your solution is to either use await:
try {
await doSomethingAsyncThatWillTrowLater();
} catch (e) {
}
Or use Future.catchError/Future.then:
doSomethingAsyncThatWillTrowLater().catchError((error) {
print('Error: $error');
});
From the docs,
If the catch clause does not specify a type, that clause can handle any type of thrown object:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e'); <------------------
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
Change it to this:
try {
_updateCurrentUserEmail();
} on Exception catch(e){
print('error caught: $e')
}
Another way to handle error is to do the following:
void _updateCurrentUserEmail() async {
await FirebaseAuth.instance
.currentUser()
.then((FirebaseUser user) {
_email = user.email;
throw("some arbitrary error");
});
.catchError(handleError);
}
handleError(e) {
print('Error: ${e.toString()}');
}
If currentUser()’s Future completes with a value, then()’s callback fires. If code within then()’s callback throws (as it does in the example above), then()’s Future completes with an error. That error is handled by catchError().
Check the docs:
https://dart.dev/guides/libraries/futures-error-handling
Throw
Here’s an example of throwing, or raising, an exception:
throw FormatException('Expected at least 1 section');
You can also throw arbitrary objects:
throw 'Out of llamas!';
throwing an exception is an expression, you can throw exceptions in => statements, as well as anywhere else that allows expressions:
void someMethod(Point other) => throw UnimplementedError();
here is example
main() {
try {
test_age(-2);
}
catch(e) {
print('Age cannot be negative');
}
}
void test_age(int age) {
if(age<0) {
throw new FormatException();
}
}
hope it helps..
I have a HTML5 worker which sends values with postMessage. Sometimes (for example if the result is a function) the code throws an exception:
DataCloneError: The object could not be cloned.
So I tried to catch the exception:
try {
self.postMessage (result);
}
catch (ex) {
if (ex instanceof DataCloneError)
self.postMessage (result.toString());
else
throw ex;
}
But this throws the following exception:
ReferenceError: DataCloneError is not defined
I am confused. How to catch the DataCloneError?
The error you receive is an instance of the DOMException interface.
To know which DOMException it is, you can check its name property.
The one of DATA_CLONE_ERROR, is "DataCloneError".
try {
postMessage( () => {} , '*' );
}
catch( err ) {
console.log( err.name === "DataCloneError" );
}
I have an application with both MVC and 'new' ApiController endpoints in ASP.NET Core 2.2 co-existing together.
Prior to adding the API endpoints, I have been using a global exception handler registered as middleware using app.UseExceptionHandler((x) => { ... } which would redirect to an error page.
Of course, that does not work for an API response and I would like to return an ObjectResult (negotiated) 500 result with a ProblemDetails formatted result.
The problem is, I'm not sure how to reliably determine in my 'UseExceptionHandler' lambda if I am dealing with an MVC or a API request. I could use some kind of request URL matching (eg. /api/... prefix) but I would like a more robust solution that won't come back to bite me in the future.
Rough psuedo-code version of what I'm trying to implement is:
app.UseExceptionHandler(x =>
{
x.Run(async context =>
{
// extract the exception that was thrown
var ex = context.Features.Get<IExceptionHandlerFeature>()?.Error;
try
{
// generically handle the exception regardless of what our response needs to look like by logging it
// NOTE: ExceptionHandlerMiddleware itself will log the exception
// TODO: need to find a way to see if we have run with negotiation turned on (in which case we are API not MVC!! see below extensions for clues?)
// TODO: ... could just use "/api/" prefix but that seems rubbish
if (true)
{
// return a 500 with object (in RFC 7807 form) negotiated to the right content type (eg. json)
}
else
{
// otherwise, we handle the response as a 500 error page redirect
}
}
catch (Exception exofex)
{
// NOTE: absolutely terrible if we get into here
log.Fatal($"Unhandled exception in global error handler!", exofex);
log.Fatal($"Handling exception: ", ex);
}
});
});
}
Any ideas?
Cheers!
This might be a bit different than what you expect, but you could just check if the request is an AJAX request.
You can use this extension:
public static class HttpRequestExtensions
{
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
if (request.Headers == null)
return false;
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
}
And then middleware with an invoke method that looks like:
public async Task Invoke(HttpContext context)
{
if (context.Request.IsAjaxRequest())
{
try
{
await _next(context);
}
catch (Exception ex)
{
//Handle the exception
await HandleExceptionAsync(context, ex);
}
}
else
{
await _next(context);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
//you can do more complex logic here, but a basic example would be:
var result = JsonConvert.SerializeObject(new { error = "An unexpected error occurred." });
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
return context.Response.WriteAsync(result);
}
see this SO answer for a more detailed version.
If you want to check whether the request is routed to ApiController, you could try IExceptionFilter to hanlde the exceptions.
public class CustomExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (IsApi(context))
{
HttpStatusCode status = HttpStatusCode.InternalServerError;
var message = context.Result;
//You can enable logging error
context.ExceptionHandled = true;
HttpResponse response = context.HttpContext.Response;
response.StatusCode = (int)status;
response.ContentType = "application/json";
context.Result = new ObjectResult(new { ErrorMsg = message });
}
else
{
}
}
private bool IsApi(ExceptionContext context)
{
var controllerActionDesc = context.ActionDescriptor as ControllerActionDescriptor;
var attribute = controllerActionDesc
.ControllerTypeInfo
.CustomAttributes
.FirstOrDefault(c => c.AttributeType == typeof(ApiControllerAttribute));
return attribute == null ? false : true;
}
}
Thanks to all of the advice from others, but I have realised after some more thought and ideas from here that my approach wasn't right in the first place - and that I should be handling most exceptions locally in the controller and responding from there.
I have basically kept my error handling middleware the same as if it was handling MVC unhandled exceptions. The client will get a 500 with a HTML response, but at that point there isn't much the client can do anyway so no harm.
Thanks for your help!
So I'm experimenting with a try/catch clause, and I don't understand why this is happening (normal or not):
void main() {
List someList = [1,2,3];
try {
for (var x in someList) {
try {
for (var z in x) {
}
} catch(e) {
throw new Exception('inside');
}
}
} catch(e) {
throw new Exception('outside');
}
}
So you see I'm trying to do a loop inside a loop, but on purpose, someList is not a List<List>, therefore the nested loop will throw an error ('inside' error) since 1 is an int, not a List.
That's the scenario, but what happens is it throws the 'outside' error.
Is this normal? If so, where did I go wrong?
The exception you're getting is because w is undefined. If you change w to someList, then you'll get an exception for x not having an iterator, like you expect. You'll then handle that "inside" exception and immediately throw another one, which you'll catch, and then you'll throw the "outside" one, which you don't handle and will see an error for. (This might make it look like you're getting an "outside" error, but the error started on the "inside".)
This might make things clearer:
void main() {
List someList = [1,2,3];
try {
for (var x in someList) {
try {
for (var z in x) { // This throws an exception
}
} catch(e) { // Which you catch here
print(e);
print("Throwing from inside");
throw new Exception('inside'); // Now you throw another exception
}
}
} catch(e) { // Which you catch here
print(e);
print("Throwing from outside");
throw new Exception('outside'); // Now you throw a third exception
}
} // Which isn't caught, causing an
// "Unhandled exception" message