This question already has an answer here:
How can I catch all crash exception in monotouch/ios?
(1 answer)
Closed 5 years ago.
I am trying to display an alert when an exception occurs and bubbles up to the iOS project.Main
Now let's suppose I have an "Object variable not set exception" somewhere in the program
it bubbles to the MyApp.IOS project but no UI alert pops up!!
public class Application
{
static void Main(string[] args)
{
try
{
UIApplication.Main(args, null, "AppDelegate");
}
catch (Exception ex)
{
Task.Run(() =>
{
Device.BeginInvokeOnMainThread(() => {
ShowAlert("MyTitle", ex.ToString(), UIApplication.SharedApplication.KeyWindow.RootViewController);
});
});
}
}
public static UIAlertController ShowAlert(string title, string description, UIViewController controller)
{
UIAlertController alert = UIAlertController.Create(title, description, UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, (action) => { }));
controller.PresentViewController(alert, true, null);
return alert;
}
}
any ideas what I am missing?
Is not possible catch the error and show the alert. Check the information about the native crash. And check the log files.
How can I catch all crash exception in monotouch/ios?
Related
Hello Liferay Experts,
I have a requirement where I need to stop an Admin from assigning a role, I am trying to implement this with a ModelListener.
Here is the code..
#Component(immediate = true, service = ModelListener.class)
public class TestUserModelListener extends BaseModelListener<User> {
#Override
public void onBeforeAddAssociation(Object classPK, String associationClassName, Objext accociationClassPK) throws ModelListenerException {
// ...
throw new ModelListenerException("User creation not allowed");
}
}
When this code executes, the exception is thrown but the UI doesnt handle it correctly, the control panel Menus are not displayed and the exception message is not displayed to the user.
How to throw an exception and handle it correctly in UI and display error message to the user.
Thanks
M
Andre Albert already gave you the correct hints in the comments.
You should keep the ModelListener and override the ActionCommand additionally.
First, read the tutorial about Overriding MVC Comands. When implementing your custom Command, use Liferay's implemenation as basis (don't forget to add the higher service.ranking) and replace the catch block with something like this:
// I took the freedom and refactored Liferay's catch block a little bit
catch (NoSuchUserException | PrincipalException e) {
SessionErrors.add(actionRequest, e.getClass());
actionResponse.setRenderParameter("mvcPath", "/error.jsp");
} catch (MembershipPolicyException e) {
SessionErrors.add(actionRequest, e.getClass(), e);
actionResponse.setRenderParameter("mvcPath", "/edit_user.jsp");
actionResponse.setRenderParameter("screenNavigationCategoryKey", UserFormConstants.CATEGORY_KEY_GENERAL);
actionResponse.setRenderParameter("screenNavigationEntryKey", UserFormConstants.ENTRY_KEY_ROLES);
} catch (ForbiddenRoleAssociationException e) {
// Here you can add a SessionError
// and set some render parameters
} catch (Exception e) {
throw e;
}
The ForbiddenRoleAssociationException does not exist yet. It's purpose is to distinguish this special case of a ModelListenerException from others which might not interest you. You'll have to implement it yourself. Just extend the ModelListenerException:
public class ForbiddenRoleAssociationException extends ModelListenerException {
// here might be some constructors
}
Now adjust your ModelListener so that it throws your new ForbiddenRoeAssociationException:
#Component(immediate = true, service = ModelListener.class)
public class TestUserModelListener extends BaseModelListener<User> {
#Override
public void onBeforeAddAssociation(Object classPK, String associationClassName, Objext accociationClassPK) throws ModelListenerException {
// ...
throw new ForbiddenRoleAssociationException(); // or any other constructor
}
}
This way you should be able to display error messages to admins (depending on your code in the catch block of the ForbiddenRoleAssociationException) and circumvent any other (programmatic) attempt to assign the Role as well.
This question is specific to a lately strange behavior of the Azure mobile Apps Android sdk. Everything was working fine for weeks. Now, my android client app suddenly can't connect to my web app any more. A Toast says "Error while processing request". In Android Studio debugger, I found the exception inside the SDK file MobileServiceConnection.java.
java.io.IOException: stream was reset: PROTOCOL_ERROR
In Azure Portal, my app shows "Healthy" status, but I can see the HTTP errors. Please help.
Following is my code, which was working fine and now throws error.
// Create the Mobile Service Client instance, using the provided mobile app URL.
try {
mClient = new MobileServiceClient(mMobileBackendUrl, activityContext).withFilter(
new ServiceFilter() {
#Override
public ListenableFuture<ServiceFilterResponse> handleRequest(ServiceFilterRequest request, NextServiceFilterCallback nextServiceFilter) {
// Get the request contents
String url = request.getUrl();
String content = request.getContent();
if (url != null) {
Log.d("Request URL:", url);
}
if (content != null) {
Log.d("Request Content:", content);
}
// Execute the next service filter in the chain
ListenableFuture<ServiceFilterResponse> responseFuture = nextServiceFilter.onNext(request);
Futures.addCallback(responseFuture, new FutureCallback<ServiceFilterResponse>() {
#Override
public void onFailure(Throwable exception) {
Log.d("Exception:", exception.getMessage());
}
#Override
public void onSuccess(ServiceFilterResponse response) {
if (response != null && response.getContent() != null) {
Log.d("Response Content:", response.getContent());
}
}
});
return responseFuture;
}
}
);
setAzureClient(mClient);
}catch(MalformedURLException e){
createAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
}catch(Exception e){
createAndShowDialog("There was an error creating the Mobile Service. "+ e.toString(), "Error");
}
Toast.makeText(context, context.getString(R.string.online_authentication), Toast.LENGTH_SHORT).show();
authenticate();
}
private void authenticate() { // give access only to authenticated users via Google account authentication
HashMap<String, String> parameters = new HashMap<>();
parameters.put("access_type", "offline");//use "Refresh tokens"
//login with the Google provider. This will create a call to onActivityResult() method inside the context Activity, which will then call the onActivityResult() below.
mClient.login(MobileServiceAuthenticationProvider.Google, url_scheme_of_your_app, GOOGLE_LOGIN_REQUEST_CODE, parameters);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// When request completes
if (requestCode == 1) {
try {
MobileServiceActivityResult result = mClient.onActivityResult(data);
if (result.isLoggedIn()) {
Toast.makeText(context, context.getString(R.string.azure_auth_login_success) /*+ " " + mClient.getCurrentUser().getUserId()*/, Toast.LENGTH_SHORT).show();
mUserId = mClient.getCurrentUser().getUserId();
} else {//>>>>THIS IS WHERE I AM GETTING THE ERROR
String errorMessage = result.getErrorMessage();
Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT).show();// Error While processing request (it comes form the MobileServiceConnection.java file inside sdk)
}
}catch(Exception e){
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
I found the answer myself. The error was due to an Azure App Service HTTP2 connection issue. It has nothing to do with the app code. For anyone facing the same problem, here is the solution.
Go to https://resources.azure.com/
Make sure you are in Read/Write mode by clicking in the option to the left of your name.
From the left column, browse to: https://resources.azure.com/subscriptions/yourSubscriptionId/resourceGroups/yourWebAppResourceGroup/providers/Microsoft.Web/sites/yourWebAppName/config/web
Find and Change the property: "http20Enabled": from true to false by clicking EDIT, Update value to “false” and then clicking in Save or PATCH.
I'm trying to use the ServiceExceptionHandler on my Serivce which extends RestServiceBase<TViewModel>
I can use the AppHost.ServiceExceptionHandler, that's working fine. I need the user info from the HttpRequest, thats not available at AppHost level.
So I'm trying to use the ServiceExceptionHandler on Service level. Though I set the delegate on service ctor, it's null when exception thrown on OnGet method
public class StudentService : RestServiceBase<Student>
{
public StudentService()
{
ServiceExceptionHandler = (request, exception) =>
{
logger.Error(string.Format("{0} - {1} \n Request : {2}\n", HttpRequest.UserName(), exception.Message, request.Dump()), exception);
var errors = new ValidationErrorField[] { new ValidationErrorField("System Error", "TODO", "System Error") };
return DtoUtils.CreateErrorResponse("System Error", "System Error", errors);
};
}
}
I'm not sure of what is the issue with this code. Any help will be appreciated.
Register Global AppHost.ServiceExceptionHandler
In your AppHost.Configure() you can register a global Exception handler with:
this.ServiceExceptionHandler = (request, ex) => {
... //handle exception and generate your own ErrorResponse
};
For finer-grained Exception handlers you can override the following custom service event hooks:
Handling Exceptions with the New API
If you're using the New API you can override the Exception by providing a custom runner, e.g:
public class AppHost {
...
public virtual IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
ActionContext actionContext)
{
//Cached per Service Action
return new ServiceRunner<TRequest>(this, actionContext);
}
}
public class MyServiceRunner<T> : ServiceRunner<T> {
public override object HandleException(
IRequestContext requestContext, TRequest request, Exception ex) {
// Called whenever an exception is thrown in your Services Action
}
}
Handling Exceptions with the Old API
RestServiceBase<T> is uses the old API in which you can handle errors by overriding the HandleException method, e.g:
public class StudentService : RestServiceBase<Student>
{
...
protected override object HandleException(T request, Exception ex)
{
LogException(ex);
return base.HandleException(request, ex);
}
}
I have written following piece of code. It is used to create camera player. I tested it on nokia phones. It's working fine and I am able to see camera and use its functionality.
But the issue is that when the code is tested on samsung phone it throws Media exception and eventually have to make an exit from the application. Due to this code, my inbuilt camera functionality (i.e. on samsung phone) also stops working. So what's the reason to it?
public void startCamera()
{
try
{
try
{
// if player==null
player = createPlayer();
}
catch (Exception ex)
{
ex.printStackTrace();
ErrorDialog.show(ex, "We are exiting the application.",
"Exit", new com.auric.qrev.scanqrcode.lwuit.ui.Action(){
public void actionPerformed() {
m_objMIDlet.exitApp();
}
});
}
try
{
player.realize();
player.prefetch();
}
catch (MediaException ex)
{
ex.printStackTrace();
ErrorDialog.show(ex, "We are exiting the application.",
"Exit", new com.auric.qrev.scanqrcode.lwuit.ui.Action(){
public void actionPerformed() {
m_objMIDlet.exitApp();
}
});
}
//Grab the video control and set it to the current display.
videoControl = (VideoControl)(player.getControl("VideoControl"));
if (videoControl == null)
{
//discardPlayer();
stopCamera();
ErrorDialog.show("Unsupported:\n"+
"Can't get video control\n"+
"We are exiting the application.",
"Exit", new com.auric.qrev.scanqrcode.lwuit.ui.Action(){
public void actionPerformed() {
m_objMIDlet.exitApp();
}
});
}
mediaComponent = new MediaComponent(player);
mediaComponent.setFocusable(false);
m_cameraScreen.showCamera(mediaComponent);
start();
}
catch(Exception ex)
{
ex.printStackTrace();
//discardPlayer();
stopCamera();
ErrorDialog.show("Sorry,Resources unavailable.\nWe are exiting the application.",
"Exit", new com.auric.qrev.scanqrcode.lwuit.ui.Action(){
public void actionPerformed() {
m_objMIDlet.exitApp();
}
});
}
}
private Player createPlayer()throws MediaException, Exception
{
Player mPlayer = null;
// try capture://image first for series 40 phones
try
{
mPlayer = Manager.createPlayer("capture://image");
}
catch (Exception e)
{
e.printStackTrace();
}
catch (Error e)
{
e.printStackTrace();
}
// if capture://image failed, try capture://video
if (mPlayer == null)
{
try
{
mPlayer = Manager.createPlayer("capture://video");
}
catch (Exception e)
{
e.printStackTrace();
throw new MediaException("Sorry,Resources unavailable.");
}
}
if(mPlayer == null)
throw new Exception("Sorry,Resources unavailable.");
return mPlayer;
}
First things first, you have to realize that printStackTrace() is pretty much useless outside of the emulator unless you are using a Symbian phone.
You can also use java.lang.Throwable instead of separating Exception and Error
You can figure out exactly what happens by gathering information as a String and appending it to a simple lcdui Form while you are testing:
try {
// do something that could potentially fail
} catch (Throwable th) {
myDebugLcduiForm.append("potential failure number xx." + th + th.getMessage());
// if necessary, throw a new RuntimeException
}
You might want to update/repost your question once you know exactly what line of code throws what exception.
I am looking to develop an error handling strategy for a SharePoint solution that makes use of sandboxed webparts. I was initially looking at a general exception handling approach based on this article, but this doesn't work for sandboxed webparts. Once an unhandled exception has been thrown in the sandbox, the user code service appears to take control, so that the exception handling in the base web part isn't reached. Are there any established error handling approaches for sandboxed solutions?
Is anyone aware of a method of determining when an unhandled exception has been thrown in a sandboxed webpart, if only to change the displayed error message to a more user friendly message? I would like to replace the standard "Web Part Error: Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust app domain: An unexpected error has occurred." message at very least.
Thanks, MagicAndi.
Actually, you can follow the approach suggested by the article you mentioned. You just have to provide safe overridables for all virtual properties and methods your descendant web parts are going to override. The patter can be described:
Override and seal every virtual property and method supposed to be overriden with code that can throw an exception.
Create a virtual counterpart of the overridable with the same prototype and call the base class from it if necessary. This is supposed to be overriden by your descendants.
Call the new overridable from the sealed member in a try&catch and remember the exception if caught there.
Rendering method either renders the usual content or the remembered error message.
This is a torso of the base class I use:
public class ErrorSafeWebPart : WebPart {
#region Error remembering and rendering
public Exception Error { get; private set; }
// Can be used to skip some code later that needs not
// be performed if the web part renders just the error.
public bool HasFailed { get { return Error != null; } }
// Remembers just the first error; following errors are
// usually a consequence of the first one.
public void RememberError(Exception error) {
if (Error != null)
Error = error;
}
// You can do much better error rendering than this code...
protected virtual void RenderError(HtmlTextWriter writer) {
writer.WriteEncodedText(Error.ToString());
}
#endregion
#region Overriddables guarded against unhandled exceptions
// Descendant classes are supposed to override the new DoXxx
// methods instead of the original overridables They should
// not catch exceptions and leave it on this class.
protected override sealed void CreateChildControls() {
if (!HasFailed)
try {
DoCreateChildControls();
} catch (Exception exception) {
RememberError(exception);
}
}
protected virtual void DoCreateChildControls()
{}
protected override sealed void OnInit(EventArgs e) {
if (!HasFailed)
try {
DoOnInit(e);
} catch (Exception exception) {
RememberError(exception);
}
}
protected virtual void DoOnInit(EventArgs e) {
base.OnInit(e);
}
// Continue similarly with OnInit, OnLoad, OnPreRender, OnUnload
// and/or others that are usually overridden and should be guarded.
protected override sealed void RenderContents(HtmlTextWriter writer) {
// Try to render the normal contents if there was no error.
if (!HasFailed)
try {
DoRenderContents(writer);
} catch (Exception exception) {
RememberError(exception);
}
// If an error occurred in any phase render it now.
if (HasFailed)
RenderError(writer);
}
protected virtual void DoRenderContents(HtmlTextWriter writer) {
base.RenderContents(writer);
}
#endregion
}
--- Ferda