I am using libgdx and robovm.
I get an error when I try to submit the score to the leaderboard on GameCenter on iOS. I am able to show the leaderboard. This is the error I get:
*** Terminating app due to uncaught exception 'GKInvalidArgumentException', reason: 'A GKScore must specify a leaderboard.'
libc++abi.dylib: terminating with uncaught exception of type NSException
It is similar to this SO-post, but it is objective-c so I dont understand the answer.
This is my code for showing the leaderboard (this works)
public void getLeaderboardGPGS() {
// If player is not authenticated, do nothing
if (!GKLocalPlayer.getLocalPlayer().isAuthenticated()) {
return;
}
GKGameCenterViewController gameCenterView = new GKGameCenterViewController();
gameCenterView.setGameCenterDelegate(new GKGameCenterControllerDelegateAdapter() {
#Override
public void didFinish (GKGameCenterViewController gameCenterViewController) {
dismissViewControllerAndNotifyListener(gameCenterViewController, GKGameCenterViewControllerState.Leaderboards);
}
});
gameCenterView.setViewState(GKGameCenterViewControllerState.Leaderboards);
gameCenterView.setLeaderboardIdentifier(identifier);
keyWindow.getRootViewController().presentViewController(gameCenterView, true, null);
}
This is my code for submiting the score (this does not work)
public void submitScoreGPGS(int score, MyLeaderBoardCallback callback) {
// If player is not authenticated, do nothing
if (!GKLocalPlayer.getLocalPlayer().isAuthenticated()) {
//listener.scoreReportFailed(buildUnauthenticatedPlayerError());
Gdx.app.log("Gamecenter","Notlogedin");
return;
}
GKScore scoreReporter = new GKScore(identifier);
scoreReporter.setValue(score);
scoreReporter.setLeaderboardIdentifier(identifier);
//scoreReporter.setShouldSetDefaultLeaderboard(true);
//scoreReporter.setContext(0);
NSArray<GKScore> scores = new NSArray<GKScore>(scoreReporter);
Gdx.app.log("Gamecenter","Report socre");
GKScore.reportScores(scores, new VoidBlock1<NSError>() {
#Override
public void invoke (NSError error) {
if (error != null) {
Gdx.app.log("Gamecenter","scorereportfailed");
} else {
Gdx.app.log("Gamecenter","scorereportcompleted");
}
}
});
}
Anyone knows what the problem might be? I have tried googleing but there is little information about "robovm and gamekit/gamecenter".
The variable that contained the leaderboard id was garbage collected for some reason. Had to hard-code the string at scoreReporter.setLeaderboardIdentifier("my hard coded id"); . Weird....
Related
In the clean code book is an example about using exceptions rather than return codes:
You either set an error flag or returned an error code.
public class DeviceController {
...
public void sendShutDown() {
DeviceHandle handle = getHandle(DEV1);
// Check the state of the device
if (handle != DeviceHandle.INVALID) {
// Save the device status to the record field
retrieveDeviceRecord(handle);
// If not suspended, shut down
if (record.getStatus() != DEVICE_SUSPENDED) {
pauseDevice(handle);
clearDeviceWorkQueue(handle);
closeDevice(handle);
} else {
logger.log("Device suspended. Unable to shut down");
}
} else {
logger.log("Invalid handle for: " + DEV1.toString());
}
}
...
}
Unfortunately, it's easy to forget. For this reason, it is better to throw an exception when you encounter an error. The calling code is cleaner. Its logic is not obscured by error handling.
public class DeviceController {
...
public void sendShutDown() {
try {
tryToShutDown();
} catch (DeviceShutDownError e) {
logger.log(e);
}
}
private void tryToShutDown() throws DeviceShutDownError {
DeviceHandle handle = getHandle(DEV1);
DeviceRecord record = retrieveDeviceRecord(handle);
pauseDevice(handle);
clearDeviceWorkQueue(handle);
closeDevice(handle);
}
private DeviceHandle getHandle(DeviceID id) {
...
throw new DeviceShutDownError("Invalid handle for: " + id.toString());
...
}
...
}
The code is better because two concerns that were tangled, the algorithm for device shutdown and error handling, are now separated. You can look at each of those concerns and understand them independently.
Now my question is not so much about the whether to use exceptions or return codes but I am wondering about the unused DeviceRecord in the second "good example", which uses exceptions.
Wouldn't it be enough to just call retrieveDeviceRecord(handle); to save the device status to the record field as in the "bad example code" but change the method to also throw an exception in case anything goes wrong during retrieveDeviceRecord(handle);? Or is there a purpose of returning DeviceRecord but not using it?
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.
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.
I am new to GWT. I have written a piece of code which makes asynchronous calls to the server. The server side code is running fine as seen through the logs. But on the client side I am getting a failure message.
I am trying to load large amount of data from the server. It seems like the async call times out before the entire data is returned from the server. Is there a way I can increase the timeout of the call? or is there any other issue with my code?
public MapDataServiceFacadeAsync getMapDataServiceInstance()
{
if (mapDataService == null)
{
mapDataService = MapDataServiceFacade.Util.getInstance();
}
return mapDataService;
public void setTreeInstance(final String productName, final Object invObject, final boolean isToLoadTickets, final SearchItem search)
{
refreshSearch = search;
this.inventoryMapPanel = (InventoryMapPanel) invObject;
long startTime = System.currentTimeMillis();
getMapDataServiceInstance().getProductTree(userProfile, isToLoadTickets, search, new AsyncCallback()
{
public void onFailure(Throwable caught)
{
CommonMapUI.loadLabel(false);
Window.alert("Failed to Load Tree. Please try again");
}
public void onSuccess(Object result)
{
tmpData = (MapItem[]) ((HashMap) result).get("tree");
if (tmpData == null && Count < 3)
{
Count++;
setTreeInstance(productName, invObject, isToLoadTickets, search);
}
else
{
buildProductTree(result, invObject, isToLoadTickets);
}
}
});
}
It is always throwing the error "Failed to load Tree" if I try and retrieve large amount of data. It works fine if small amount of data is to be loaded.
Interface:
public interface MapDataServiceFacadeAsync {
public void getProductTree(CommonUserProfile user, boolean isToLoadTickets,SearchItem search, AsyncCallback asynCall);
Any help would be appreciated.
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