Try-Catch not working for controller to class library [Debugger Mode] - exception

I am running dotnet core 2.* and as the title mentions I have trouble getting my try catch to work when calling from API. And before anyone comments I am also running middle-ware to catch any exceptions. It too doesn't perform as expected
Addinional Information:
The Two Classes are in different namespaces/projects
Queries.Authentication is static.
They are both in the same solution
Controller:
[AllowAnonymous]
[HttpPost]
public string Login([FromBody] AuthRequest req)
{
// See if the user exists
if (Authenticate(req.username, req.password))
{
try {
// Should Fail Below
UserDetails ud = Queries.Authentication.GetUser(req.username);
} catch (RetrievalException e){ }
catch (Exception e){ } // Exception Still Comes Through
}
}
Queries.Authentication.GetUser Code:
public static class Authentication {
public static UserDetails GetUser (string username)
{
// Some Code
if (details.success)
{
// Some Code
}
else
{
throw new RetrievalException(details.errorMessage); // This is not caught propperly
}
}
}
Retrieval Exception:
public class RetrievalException : Exception
{
public RetrievalException()
{
}
public RetrievalException(String message)
: base(message)
{
}
public RetrievalException(String message, Exception inner)
: base(message, inner)
{
}
}
EDIT: Adding Middleware Code Here as per request:
public class CustomExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
HttpStatusCode status = HttpStatusCode.InternalServerError;
String message = String.Empty;
var exceptionType = context.Exception.GetType();
if (exceptionType == typeof(UnauthorizedAccessException))
{
message = "Unauthorized Access";
status = HttpStatusCode.Unauthorized;
}
else if (exceptionType == typeof(NullReferenceException))
{
message = "Null Reference Exception";
status = HttpStatusCode.InternalServerError;
}
else if (exceptionType == typeof(NotImplementedException))
{
message = "A server error occurred.";
status = HttpStatusCode.NotImplemented;
}
else if (exceptionType == typeof(RSClientCore.RetrievalException))
{
message = " The User could not be found.";
status = HttpStatusCode.NotFound;
}
else
{
message = context.Exception.Message;
status = HttpStatusCode.NotFound;
}
context.ExceptionHandled = true;
HttpResponse response = context.HttpContext.Response;
response.StatusCode = (int)status;
response.ContentType = "application/json";
var err = "{\"message\":\"" + message + "\",\"code\" :\""+ (int)status + "\"}";
response.WriteAsync(err);
}
}
App Config:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} else
{
app.UseExceptionHandler();
}
...
}
Service Config:
public void ConfigureServices(IServiceCollection services)
{
// Add Model View Controller Support
services.AddMvc( config =>
config.Filters.Add(typeof (CustomExceptionFilter))
);
UPDATE: After playing around with it I noticed that even though my program throws the exception, if I press continue the API controller then handles it as if the exception was never thrown (as in it catches it and does what I want). So I turned off the break on Exception setting, this fixed it in debugger mode. However this the break doesn't seem to be an issue when I build/publish the program. This makes me think it is definitely a issue with visual studio itself rather than the code.

When you set ExceptionHandled to true that means you have handled the exception and there is kind of no error anymore. So try to set it to false.
context.ExceptionHandled = false;
I agree it looks a bit confusing, but should do the trick you need.
Relevant notes:
For those who deal with different MVC and API controller make sure you implemented appropriate IExceptionFilter as there are two of them - System.Web.Mvc.IExceptionFilter (for MVC) and System.Web.Http.Filters.IExceptionFilter (for API).
There is a nice article about Error Handling and ExceptionFilter Dependency Injection for ASP.NET Core APIs you could use as a guide for implementing exception filters.
Also have a look at documentation: Filters in ASP.NET Core (note selector above the left page menu to select ASP.NET Core 1.0, ASP.NET Core 1.1,ASP.NET Core 2.0, or ASP.NET Core 2.1 RC1). It has many important notes and explanations why it works as it does.

Related

How to use BroadcastReceiver with MvvmCross when app is not running

I'm working in an Android application and I'm having some trouble using the BroadcastReceiver with MvvmCross. I have the broadcast to receive messages from GCM (Push Notification) and then i create an IntentService that would do something when a message is received.
In my IntentService I use a Mvx.Resolve to make some calls to the Core project. Since the app is not running it throws an exception that it was not found (when trying to use Mvx.Resolve).
I tried finding a solution in the web and the closest i got was: How do I initialize the MvvmCross framework without a splash Activity? .
So I tried using it but I received another exception.
Android.Content.ReceiverCallNotAllowedException: Exception of type 'Android.Content.ReceiverCallNotAllowedException' was thrown
I saw this was happening when trying to create a receiver inside another receiver.
My broadcast is the following (using the code from the stack above):
[BroadcastReceiver(Permission= "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "MyPackage" }, Priority = (int)IntentFilterPriority.HighPriority)]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "MyPackage" }, Priority = (int)IntentFilterPriority.HighPriority)]
[IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "MyPackage" }, Priority = (int)IntentFilterPriority.HighPriority)]
public class GCMBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var setup = MvxAndroidSetupSingleton.EnsureSingletonAvailable(context);
setup.EnsureInitialized();
GCMIntentService.RunIntentInService(context, intent);
SetResult(Result.Ok, null, null);
}
}
My IntentService:
[Service]
public class GCMIntentService : IntentService
{
static PowerManager.WakeLock sWakeLock;
static object LOCK = new object();
public static void RunIntentInService(Context context, Intent intent)
{
lock (LOCK)
{
if (sWakeLock == null)
{
// This is called from BroadcastReceiver, there is no init.
var pm = PowerManager.FromContext(context);
sWakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "GCM Broadcast Receiver");
}
}
sWakeLock.Acquire();
intent.SetClass(context, typeof(GCMIntentService));
context.StartService(intent);
}
protected override void OnHandleIntent(Intent intent)
{
try
{
var context = this.ApplicationContext;
var action = intent.Action;
if (action.Equals("com.google.android.c2dm.intent.REGISTRATION"))
{
HandleRegistration(context, intent);
}
else if (action.Equals("com.google.android.c2dm.intent.RECEIVE"))
{
HandleMessage(context, intent);
}
}
finally
{
lock (LOCK)
{
//Sanity check for null as this is a public method
if(sWakeLock != null)
{
sWakeLock.Release();
}
}
}
}
private void HandleRegistration(Context context, Intent intent)
{
var registration = intent.GetStringExtra("registration_id");
if(intent.GetStringExtra("error") != null)
{
// Registration failed, should try again later.
}
else if(intent.GetStringExtra("unregistered") != null)
{
// Unregistered
}
else if(registration != null)
{
//Do registration
}
}
private void HandleMessage(Context context, Intent intent)
{
Task.Factory.StartNew(() =>
{
Mvx.Resolve<MyInterface>().DoSomething();
});
}
}
I read in that same stack overflow that if I was using only a simple Mvx.Resolve it would be easier to instantiate it by myself. The problem is that inside my method "DoSomething" it uses more Mvx.Resolves and I didn't want to change the core application because of the Android.
So I was wondering if there is any way to start the framework so that I would not have to change the Core or if the best way to deal with this would be changing the core.
Edit:
The Exception Trace is (I got this from the logcat since i can't debug an app that is not running):
Android.Content.ReceiverCallNotAllowedException: Exception of type 'Android.Content.ReceiverCallNotAllowedException' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0x00028>
at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x000c3>
at Android.Content.ContextWrapper.RegisterReceiver (Android.Content.BroadcastReceiver,Android.Content.IntentFilter) <0x0018f>
at Thrust.Plugins.Network.Droid.NetworkService.OnNetworkChanged (System.Action`1<Thrust.Plugins.Network.NetworkStatus>) <0x00093>
at Chat.Core.App.Initialize () <0x00533>
at Cirrious.MvvmCross.Platform.MvxSetup.CreateAndInitializeApp (Cirrious.CrossCore.Plugins.IMvxPluginManager) <0x0005b>
at Cirrious.MvvmCross.Platform.MvxSetup.InitializeApp (Cirrious.CrossCore.Plugins.IMvxPluginManager) <0x00027>
at Cirrious.MvvmCross.Platform.MvxSetup.InitializeSecondary () <0x00133>
at Cirrious.MvvmCross.Platform.MvxSetup.Initialize () <0x0002b>
at Cirrious.MvvmCross.Droid.Platform.MvxAndroidSetupSingleton.EnsureInitialized () <0x0011b>
at Chat.Droid.GCM.GCMBroadcastReceiver.OnReceive (Android.Content.Context,Android.Content.Intent) <0x0002b>
at Android.Content.BroadcastReceiver.n_OnReceive_Landroid_content_Context_Landroid_content_Intent_ (intptr,intptr,intptr,intptr) <0x0007b>
at (wrapper dynamic-method) object.0daa077c-c2f5-4cd5-bcbc-bc391ce0b2c3 (intptr,intptr,intptr,intptr) <0x0004b>
--- End of managed exception stack trace ---
android.content.ReceiverCallNotAllowedException: BroadcastReceiver components are not allowed to register to receive intents
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:246)
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:235)
at chat.droid.gcm.GCMBroadcastReceiver.n_onReceive(Native Method)
at chat.droid.gcm.GCMBroadcastReceiver.onReceive(GCMBroadcastReceiver.java:28)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2659)
at android.app.ActivityThread.access$1800(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1383)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
[ERROR] FATAL UNHANDLED EXCEPTION: Android.Content.ReceiverCallNotAllowedException: Exception of type 'Android.Content.ReceiverCallNotAllowedException' was thrown.

How to catch the play.api.libs.openid.Errors$AUTH_CANCEL$ exception?

Using Play Framework 2.1 with OpenID, if I cancel my authentication from the OpenID Provider, I get this exception :
[RuntimeException: play.api.libs.openid.Errors$AUTH_CANCEL$]
Here's my code :
Promise<UserInfo> userInfoPromise = OpenID.verifiedId();
UserInfo userInfo = userInfoPromise.get(); // Exception thrown here
But since it's a Runtime exception, I can't catch it with a try/catch so I'm stuck on how to avoid exception and returns something nicer than a server error to the client.
How can I do that?
A Promise is success biased, for all its operations, it assumes it actually contains a value and not an error.
You get the exception because you try to call get on a promise which contains an untransformed error.
What you want is to determine if the Promise is a success or an error, you can do that with pattern matching for instance.
try this code:
AsyncResult(
OpenID.verifiedId.extend1( _ match {
case Redeemed(info) => Ok(info.attributes.get("email").getOrElse("no email in valid response"))
case Thrown(throwable) => {
Logger.error("openid callback error",throwable)
Unauthorized
}
}
)
)
You may want to read more on future and promises, I recommend this excellent article :
http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html
edit :
checking the documentation (http://www.playframework.com/documentation/2.1.0/JavaOpenID) in java it seems you are supposed to catch and handle exceptions yourself.
In any case, you should catch exceptions and if one is thrown redirect
back the user to the login page with relevant information.
something like this should work :
public class Application extends Controller {
public static Result index() {
return ok("welcome");
}
public static Result auth() {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("email", "http://schema.openid.net/contact/email");
final Promise<String> stringPromise = OpenID.redirectURL("https://www.google.com/accounts/o8/id", "http://localhost:9000/auth/callback",attributes);
return redirect(stringPromise.get());
}
public static Result callback() {
try{
Promise<UserInfo> userInfoPromise = OpenID.verifiedId();
final UserInfo userInfo = userInfoPromise.get();
System.out.println("id:"+userInfo.id);
System.out.println("email:"+userInfo.attributes.get("email"));
return ok(userInfo.attributes.toString());
} catch (Throwable e) {
System.out.println(e.getMessage());
e.printStackTrace();
return unauthorized();
}
}
}

What is the right way to deal with exceptions in Castle Windsor's UsingFactoryMethod?

I'm using the Nhibernate persistence facility from Windor's tutorial:
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(config.BuildSessionFactory)
.LifeStyle.Singleton,
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifeStyle.PerWebRequest);
Sometimes my call to config.BuildSessionFactory will fail (maybe my mappings are wrong, or my connection string is invalid or whatever). In the debugger, I can see the Nhibernate exception being thrown. Now Windsor can no longer resolve my ISession either because the factory itself couldn't be instantiated.
The problem is that it doesn't seem to complain about it. Without the debugger, the exception is silently thrown away and the only symptom I have in my app is that all my ISession dependencies are suddenly null. What's the right way to deal with exceptions in UsingFactoryMethod? Is there some way I can tell Windsor to bubble up this exception to my app?
The only why I can see Castle eating the exception is if the session is being injected as a property, which makes Castle consider it optional.
Here's how I fixed it... I created an activator that throws an exception when it fails to set a property's value:
public class StrictComponentActivator : DefaultComponentActivator
{
public StrictComponentActivator(ComponentModel model, IKernelInternal kernel,
ComponentInstanceDelegate onCreation,
ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction) { }
protected override void SetUpProperties(object instance, CreationContext context)
{
instance = ProxyUtil.GetUnproxiedInstance(instance);
var resolver = Kernel.Resolver;
foreach(var property in Model.Properties)
{
var value = ObtainPropertyValue(context, property, resolver);
if(value != null)
{
var setMethod = property.Property.GetSetMethod();
try
{
setMethod.Invoke(instance, new[] { value });
}
catch(Exception ex)
{
throw new ComponentActivatorException(
string.Format(
"Error setting property {1}.{0} " +
"in component {2}. " +
"See inner exception for more information. " +
"If you don't want Windsor to set this property " +
"you can do it by either decorating it with " +
"DoNotWireAttribute or via registration API.",
property.Property.Name,
instance.GetType().Name,
Model.Name),
ex, Model);
}
}
}
}
private object ObtainPropertyValue(CreationContext context, PropertySet property, IDependencyResolver resolver)
{
if(property.Dependency.IsOptional == false ||
resolver.CanResolve(context, context.Handler, Model, property.Dependency))
{
try
{
return resolver.Resolve(context, context.Handler, Model, property.Dependency);
}
catch(Exception e)
{
if(property.Dependency.IsOptional == false)
{
throw;
}
Kernel.Logger.Warn(
string.Format("Exception when resolving optional dependency {0} on component {1}.",
property.Dependency, Model.Name), e);
}
}
return null;
}
}
And then I configured most of my components with .Activator<StrictComponentActivator>()

How should I handle exceptions within a controller constructor in WebAPI?

Say I have a constructor where it's initialization can potentially throw an exception due to reasons beyond my control.
FantasticApiController(IAwesomeGenerator awesome,
IBusinessRepository repository, IIceCreamFactory factory)
{
Awesome = awesome;
Repository = repository;
IceCream = factory.MakeIceCream();
DoSomeInitialization(); // this can throw an exception
}
Ordinarily, when a Controller action in WebAPI throws an exception I can handle it via a csutom ExceptionFilterAttribute:
public class CustomErrorHandler
{
public override void OnException(HttpActionExecutedContext context)
{
// Critical error, this is real bad.
if (context.Exception is BubonicPlagueException)
{
Log.Error(context.Exception, "CLOSE EVERYTHING!");
Madagascar.ShutdownAllPorts();
}
// No big deal, just show something user friendly
throw new HttpResponseException(new HttpResponseMessage
{
Content = new StringContent("Hey something bad happened. " +
"Not closing the ports though"),
StatusCode = HttpStatusCode.InternalServerError;
});
}
So if I have a have a BoardPlane API method which throws a BubonicPlagueException, then my CustomerErrorHandler will shut down the ports to Madagascar and log it as an error as expected. In other instances when it's not really serious, I just display some user friendly message and return a 500 InternalServerError.
But in those cases where DoSomeInitialization throws an exception, this does absolutely nothing. How can I handle exceptions in WebAPI controller constructors?
The WebApi Controllers are created, and thus constructors called via HttpControllerActivators. The default activator is System.Web.Http.Dispatcher.DefaultHttpControllerActivator.
Very rough examples for options 1 & 2 on github here https://github.com/markyjones/StackOverflow/tree/master/ControllerExceptionHandling/src
Option 1 which works quite nicely involves the use of a DI container (you may well be using one already). I have used Ninject for my example and have used "Interceptors" Read More to intercept and try/catch calls to the Create method on the DefaultHttpControllerActivator. I know of at least AutoFac and Ninject that can do something simlar to to the following:
Create the interceptor
I don't know what the lifetime scope of your Madagascar and Log items are but they could well be injected into your Interceptor
public class ControllerCreationInterceptor : Ninject.Extensions.Interception.IInterceptor
{
private ILog _log;
private IMadagascar _madagascar;
public ControllerCreationInterceptor(ILog log, IMadagascar madagascar)
{
_log = log;
_madagascar = madagascar;
}
But keeping to the example in your question where Log and Madagascar are some kind of Static global
public class ControllerCreationInterceptor : Ninject.Extensions.Interception.IInterceptor
{
public void Intercept(Ninject.Extensions.Interception.IInvocation invocation)
{
try
{
invocation.Proceed();
}
catch(InvalidOperationException e)
{
if (e.InnerException is BubonicPlagueException)
{
Log.Error(e.InnerException, "CLOSE EVERYTHING!");
Madagascar.ShutdownAllPorts();
//DO SOMETHING WITH THE ORIGIONAL ERROR!
}
//DO SOMETHING WITH THE ORIGIONAL ERROR!
}
}
}
FINALLY Register the interceptor In global asax or App_Start (NinjectWebCommon)
kernel.Bind<System.Web.Http.Dispatcher.IHttpControllerActivator>()
.To<System.Web.Http.Dispatcher.DefaultHttpControllerActivator>().Intercept().With<ControllerCreationInterceptor>();
Option 2 is to implement your own Controller Activator implementing the IHttpControllerActivator interface and handle the error in creation of the Controller in the Create method. You could use the decorator pattern to wrap the DefaultHttpControllerActivator:
public class YourCustomControllerActivator : IHttpControllerActivator
{
private readonly IHttpControllerActivator _default = new DefaultHttpControllerActivator();
public YourCustomControllerActivator()
{
}
public System.Web.Http.Controllers.IHttpController Create(System.Net.Http.HttpRequestMessage request, System.Web.Http.Controllers.HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
try
{
return _default.Create(request, controllerDescriptor, controllerType);
}
catch (InvalidOperationException e)
{
if (e.InnerException is BubonicPlagueException)
{
Log.Error(e.InnerException, "CLOSE EVERYTHING!");
Madagascar.ShutdownAllPorts();
//DO SOMETHING WITH THE ORIGIONAL ERROR!
}
//DO SOMETHING WITH THE ORIGIONAL ERROR!
return null;
}
}
}
Once you have your own custom activator the default activator can be switched out in the global asax :
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new YourCustomControllerActivator());
Option 3 Of course if your initialisation in the constructor doesn't need access to the actual Controllers methods, properties etc... i.e. assuming it could be removed from the constructor... then it would be far easier to just move the initialisation to a filter e.g.
public class MadagascarFilter : AbstractActionFilter
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
try{
DoSomeInitialization(); // this can throw an exception
}
catch(BubonicPlagueException e){
Log.Error(e, "CLOSE EVERYTHING!");
Madagascar.ShutdownAllPorts();
//DO SOMETHING WITH THE ERROR
}
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
}
public override bool AllowMultiple
{
get { return false; }
}
}

NullPointerException error on Implementing Location API on J2me

I am trying to implement jsr-179 APi into Nokia Symbian phone for periodic location update using setLocationListener through J2me. In emulator it is working fine. While I installed Midlet on the device nokia 5230, it is given NullPointerException and the application is automatically terminating. What might be possible causes?
Below is my class, I am instantiating object for this class on a form in netbeans
class MovementTracker implements LocationListener {
LocationProvider provider;
Location lastValidLocation;
UpdateHandler handler;
boolean done;
public MovementTracker() throws LocationException
{
done = false;
handler = new UpdateHandler();
new Thread(handler).start();
//Defining Criteria for Location Provider
/*
Criteria cr = new Criteria();
cr.setHorizontalAccuracy(500);
*/
//you can place cr inside getInstance
provider = LocationProvider.getInstance(null);
//listener,interval,timeout,int maxAge
//Passing -1 selects default interval
// provider.setLocationListener(MovementTracker.this, -1, -1, -1);
provider.setLocationListener(MovementTracker.this, -1, 30000, 30000);
}
public void locationUpdated(LocationProvider provider, Location location)
{
handler.handleUpdate(location);
batteryLevel = System.getProperty("com.nokia.mid.batterylevel");
sn = System.getProperty("com.nokia.mid.networksignal");
localTime = System.currentTimeMillis();
Send_Location();
}
public void providerStateChanged(LocationProvider provider, int newState)
{
}
class UpdateHandler implements Runnable
{
private Location updatedLocation = null;
// The run method performs the actual processing of the location
public void run()
{
Location locationToBeHandled = null;
while (!done)
{
synchronized(this)
{
if (updatedLocation == null)
{
try
{
wait();
}
catch (Exception e)
{
// Handle interruption
}
}
locationToBeHandled = updatedLocation;
updatedLocation = null;
}
// The benefit of the MessageListener is here.
// This thread could via similar triggers be
// handling other kind of events as well in
// addition to just receiving the location updates.
if (locationToBeHandled != null)
processUpdate(locationToBeHandled);
}
try
{
Thread.sleep(10000); //Sleeps for 10 sec & then sends the data
}
catch (InterruptedException ex)
{
}
}
public synchronized void handleUpdate(Location update)
{
updatedLocation = update;
notify();
}
private void processUpdate(Location update)
{
latitude = update.getQualifiedCoordinates().getLatitude();
longitude = update.getQualifiedCoordinates().getLongitude();
altitude = update.getQualifiedCoordinates().getAltitude();
}
}
}
public MovementTracker() throws LocationException
...
I have not written any code for handling LocationException.
No code is very dangerous practice, just search the web for something like "java swallow exceptions".
It is quite possible that because of implementation specifics Nokia throws LocationException where emulator does not throw it. Since you don't handle exception this may indeed crash you midlet at Nokia - and you wouldn't know the reason for that because, again, you have written no code to handle it.
How can I catch that exception?
The simplest thing you can do is to display an Alert with exception message and exit the midlet after user reads and dismisses alert