9

I have a feature receiver with some long running code, hence I use SPLongOperation and delegate for better visual appearance. Basically my feature receiver looks like so:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPLongOperation.Begin("Header",
                          "Caption",
                          delegate(SPLongOperation longOperation)
    {
        //custom code here
        longOperation.End("http://url", SPRedirectFlags.Static,
                          HttpContext.Current, null);
    });
}

My problem is that when an error occurs within my custom code, the feature still is "activated" - in the features list it still displays as being activated, even though an exception occurred.

How do I throw the exception back to FeatureActivated or how do I stop the feature from appearing as "activated" even though it ran into an error?


Update:

I know already that the exception thrown inside the delegate is just not passed to the FeatureActivated method, hence the feature activated already while the delegate might still be running.

I could get around using the delegate, but to instantiation a SPLongOperation I need a Page to pass - how would I get a Page without having this.Page inside a feature receiver?

The following should work:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    //Here I need to pass the ManageFeatures.aspx page? Any page? The LongRunningOperation.aspx page?
    Page page = new Page();
    SPLongOperation operation = new SPLongOperation(page);
    operation.Begin();

    //custom code here

    operation.End("http://url", SPRedirectFlags.Static,HttpContext.Current, null);
    });
}

When a feature is thrown within my custom code the exception will be passed to the feature activation and the feature will not be activated - only problem: What page to pass?

3 Answers 3

4

Found the answer:

The problem really was that the exception was being thrown within the delegate. Hence the FeatureActivated just ran smoothly and the feature seemed activated.

Fortunately SPLongOperation can be instantiated with a Page: new SPLongOperation(Page page) - problem is that in a Feature Receiver i don't have this.Page.

I found the beautiful HttpContext.Current.Handler though which can be casted as Page.
The following does the trick:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    Page page = HttpContext.Current.Handler as Page;
    SPLongOperation operation = new SPLongOperation(page);
    operation.Begin();
    try
    {
        //custom code here

        operation.End("http://url", SPRedirectFlags.Static,HttpContext.Current, null);
    }
    catch (ThreadAbortException) {}
    catch (Exception ex) {throw ex;}
}

When an Exception is thrown within the long operation, it is still thrown back to the feature receiver (FeatureActivated) and the feature fails gracefully - meaning it doesn't get activated.

5
  • 2
    This will only work when you activate the feature from the UI. Activating from PowerShell will fail, because there will not be a HttpContext.Current. Commented Aug 9, 2011 at 11:01
  • Good comment - so apparently one has to use something else than HttpContext.Current to also have it work via Powershell. Suggestions?
    – Dennis G
    Commented Aug 31, 2011 at 10:34
  • 2
    In PowerShell you don't need a SPLongOperation, because you're not going to see the screen which only will popup in the UI. If HttpContext.Current == null -> PowerShell, otherwise UI and use SPLongOperation. Commented Sep 1, 2011 at 8:53
  • Very good, could have thought of that myself :-)
    – Dennis G
    Commented Sep 1, 2011 at 14:18
  • My console application adds a feature to a SPWeb with something like this web.Features.Add(featureGuid, true);. This works fine, but when an exception is thrown in that feature's FeatureActivated event receiver, my console application has no clue of the error. Is there any way I can catch and process the error?
    – Web User
    Commented Sep 4, 2012 at 15:50
3

FeatureActivated is an asynchronous event that happens after the feature was activated. I know of no way to change the activation status except deactivating (SPFeature.Remove(id)) the feature programmatically, but not sure thats what you want...

4
  • I maybe didn't make myself clear: I am within the FeatureActivated method and I want to exit it with an error - so the feature doesn't get activated. This is possible when I throw a regular exception, but doesn't work when being within delegate of SPLongOperation.
    – Dennis G
    Commented Jun 16, 2011 at 11:13
  • No, you were clear. Like Anders says, FeatureActivated happens AFTER the feature has been activated. There's no way to 'abort' feature activation - 'cos it's already happened.
    – Andy Burns
    Commented Jun 16, 2011 at 12:27
  • 3
    Ok understood. But when I throw an exception in FeatureActivated, the feature will not be activated (or maybe internally Sharepoint deactivates is right away).
    – Dennis G
    Commented Jun 16, 2011 at 12:36
  • 3
    Even though it is the event that happens AFTER activation, when an exception is thrown inside of the event, in my experience, the feature does not remain activated. Commented Jun 16, 2011 at 12:45
2

Take a look at this blog. In the section marked SharePoint Exception Handling:

If you only catch and log the exception without throwing the SPException then the feature will complete the requested feature activation or de-activation (which ever the user is currently requesting) instead of aborting the feature activation or de-activation.

1
  • Very good information - now I only need to figure out a way to throw the exception from the delegate to the main method.
    – Dennis G
    Commented Jun 16, 2011 at 13:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.