Custom Error Page Adapter
If you are working with SharePoint 2010, see this article by Todd Carter:
An Expected Error Has Occurred
Mike has also written a nice article of the other options:
SharePoint 2010 Custom Error Messages for Public Facing Deployments
SharePoint doesn’t have an out-of-the-box support for custom error pages. Or at least it’s a little bit problematic to implement custom error pages in SharePoint context. One problem is, that SharePoint has an HttpModule that handles error scenarios in SharePoint context. If you want to implement custom error pages with your own HttpModule, you should be careful to have it before SharePoint’s modules in web.config. Because SharePoint’s HttpModule handles error scenarios in SharePoint context, you cannot use ASP.NET’s <customErrors>-tag in web.config (the redirects won’t work). Another way to implement custom error pages in SharePoint is to use control adapter. In this article I will show you how to implement one.
The first part of this solution is a SharePoint Feature:
<Feature
Id="6EE4DA6F-48A4-421b-8455-318E103A69F7"
Title="$Resources:Meteoriitti,feature_adapters_errorpage_title;"
Description="$Resources:Meteoriitti,feature_adapters_errorpage_desc;"
Version="1.0.0.0"
Scope="WebApplication"
ImageUrl="Meteoriitti/Feature.gif"
ActivateOnDefault="False"
AutoActivateInCentralAdmin="False"
ReceiverAssembly="Sininen.Meteoriitti.SharePoint.Web.UI..."
ReceiverClass="...ErrorPageControlAdapterFeatureReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementFile Location="meteoriitti_error.browser" />
</ElementManifests>
</Feature>
And the associated browser-file:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter
controlType="
Microsoft.SharePoint.ApplicationPages.ErrorPage,
Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c"
adapterType="
Sininen.Meteoriitti.SharePoint.Web.UI.ErrorPageControlAdapter,
Sininen.Meteoriitti.SharePoint.Web.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx" />
</controlAdapters>
</browser>
</browsers>
When the above Feature is activated on a web application level, the feature receiver instantiates a new timer job to copy the meteoriitti_error.browser in web application’s App_Browsers directory (see timer jobs). The timer job is used to handle farm deployment scenario where there are multiple web front ends. You can also do it manually if you like, but that’s not recommended as all manual work makes expanding SharePoint Farm more difficult.
Now we have a control adapter in place, the code for that control adapter is the last missing piece of the puzzle, so here it goes:
using System.Web;
using System.Web.UI.Adapters;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Utilities;
namespace Sininen.Meteoriitti.SharePoint.Web.UI
{
public class ErrorPageControlAdapter : PageAdapter
{
protected override void OnInit(EventArgs e)
{
var context = HttpContext.Current;
var exceptions = context.AllErrors;
var response = Page.Response;
if (exceptions == null || exceptions.Length == 0) return;
using (var web = SPContext.Current.Site.RootWeb)
{
var url = PublishingWeb.IsPublishingWeb(web)
?
SPUrlUtility.CombineUrl(
web.ServerRelativeUrl,
string.Format("{0}/Error.aspx",
PublishingWeb.GetPagesListName(web)))
:
SPUrlUtility.CombineUrl(
web.ServerRelativeUrl,
"Error.aspx");
if (string.IsNullOrEmpty(url)) return;
if (!web.GetFile(url).Exists) return;
if (url.Equals(context.Request.FilePath,
StringComparison.OrdinalIgnoreCase)) return;
// This might be a good place to log the errors.
response.Redirect(url);
}
}
}
}
The above code redirects a browser to RootWeb’s Error.aspx, or in case of publishing web to Pages/Default.aspx (localization is handled). That’s why you should provision the appropriate file to root web. The code also check if the file (Error.aspx) exists before redirecting. If it doesn’t exists the out-of-the-box error page is displayed. Also if there are errors in the error page, the code falls back to out-of-the-box error page.
Well, there is still one thing you need to take care of: the right HTTP status code! Here is an example of publishing error page’s code behind:
namespace Sininen.Meteoriitti.SharePoint.Web.UI
{
public class PublishingErrorPage : PublishingLayoutPage
{
public PublishingErrorPage()
{
Init += PublishingErrorPage_Init;
}
void PublishingErrorPage_Init(object sender, System.EventArgs e)
{
Response.StatusCode = 500;
Response.StatusDescription = "Internal Server Error";
}
}
}
One great feature of this implementation is that you can still enable debug mode just as you usually do:
MaxControls="200"
CallStack="true"
DirectFileDependencies="10"
TotalFileDependencies="50"
AllowPageLevelTrace="true">
And:
The only downside is that we need to use redirect. I tried to use rewrite, but it didn’t work. So what do you think about this?
Popularity: 4% [?]
Hi Aapo,
I went through your article and I think this is what I have been looking for but I have no idea how I can implement it in my envoirment. Can you provide step-by-step insctructions how to do it? Thanks.
Hi Bart,
Here you go (the short path):
1. Create an error.browser file like what I did in the article, and put it inside:
C:\Inetpub\wwwroot\wss\VirtualDirectories\80\App_Browsers (just an example)
(and change adapterType to point to your class)
2. Build a DLL with the adapter code I provided above and put the DLL in GAC
3. Create Error.aspx inside root webs pages library
4. Run iisreset
5. Create error in your web part, user control etc. (throw new Exception(“Testing Error Page Implementation”);) and see if its working and redirecting you to Error.aspx.
Regards
Aapo
PS. please don’t hesitate to ask more if I still wasn’t clear enough.
Bart,
Please also note that the adapter will only work if you get to SharePoint’s custom error page with some exceptions or errors: /_layouts/Error.aspx (this is what for the adapter is).
Please also note that you have to have,
<customErrors mode=”On” />, in your web.config.
Try to go to http://yourwebapp/_layouts/Error.aspx with adapter enabled and see if the adapter is executed in debugger. It will return at this point, because there wasn’t really a error:
if (exceptions == null || exceptions.Length == 0) return;
Hi Aapo,
I am implementing the samething:
1. Placed a .browser file and plcaed it under the App_browsers dierctory of the web application.
2. created a feature that tells SharePoint that about the browser file.
3. Created a class library that just redirects to http://www.google.com
But nothing worked…even there is no error getting displayed…i m just getting seeing the Error page as i was seeing previously…neither i can debug the code using the breakpoint….
i even added a safe control entry for the class library…even then the same story…
Is there any thing else i need to look upon…or i m missing something…
Thanks,
Shakti
Email – shakti.ietk.85@gmail.com
Hi All,
I was in contact with Shakti, and we figured out that there might be some problems with having separate browser-file in App_Browsers directory. If you cannot get this to work with separate browser-file, please try to include the content of that browser-file inside compat.browser.
I still don’t know why Shakti’s SharePoint couldn’t pick up the new browser file (you can try to touch compat.browser, but I think that IISRESET will do just fine). The point is that it’s working correctly in our environment, and not in Shakti’s.
So, stay tuned, maybe we can figure out the actual reason why this didn’t work in Shakti’s environment in a first place.
Hi Aapo,
thanks for clear and informative article. Interesting approach I need to test this one later… Two small suggestions: you may want to use Server.Transfere instead of Response.Redirect to redirect user to your custom error page. Maybe also some logic to verify that the exception is not 401, 403 or 404 related in which case you may want to let SharePoint handle the request/error or handle those separately.
Cheers and greetings to Tavikukko!
Hi Okko,
Yes I am aware of Server.Transfer, but you cannot use it to transfer to a publishing page that is served by SharePoint. But I agree that it would be so much better if it worked. If you can get it to work, please let me know about it.
For 404 pages I have a different approach. That isn’t handled with this adapter. Maybe I will blog about it later. For unauthorized scenarios you can handle it differently, maybe a Control Adapter for layouts/AccessDenied.aspx?
Thanks for your comments.
If you are looking on how to set the custom error page in MOSS please check my blog post http://blog.vegaitsourcing.rs/2010/03/sharepoint-custom-error-page.html
Boban,
I think you are right. But there are several problems in your approach. As you see, there is this thing called SPUtility.TransferToErrorPage, and that’s hard coded to “~/_layouts/error.aspx”. You see the problem here? So it doesn’t have to be exception that’s falling through when you end up in “~/_layouts/error.aspx”. That’s why I have this adapter, so that I’m always absolutely sure that on a public web site normal SharePoint error page is never displayed.
Your aproach doesn’t handle this:
SPUtility.TransferToErrorPage(“this totally skips the customErrors and defaultRedirect setting in web.config, and it doesn’t matter how you configure CallStack setting.”);
Hi Aapo,
I’ve been researching for this custom error page issue for more than 8 hours and finally found your post. I am trying to redirect the page for 404 and 500 error, and have tried the redirect in the CustomErrors sectoin in web.config, but found it cannot catch the 404 and 500 error in Sharepoint.
How do you know where does the error generated? How can I check if there are from the SPUtility.TransferToErrorPage?
Basically, I had 404 error when try to access a non-existing site in URL, and got 500 error when tried “Open in Excel” on an Excel webpart component after the session times out.
Thank you and great post.
Hi Aapo,
This approach does not seems tobe working for 404, 500 errors. For me 404 Errors custom page not found redirection is required, Any different approach for 404 pages?
Hi Venkat,
For 404 errors, I think it’s best to just stick with this:
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebapplication.filenotfoundpage.aspx
It’s not an optimal solution, but there hardly ever is “optimal” with SharePoint.
Hi, nice idea and well done. I wnat a way to capture server error 500 and redirected to another page .. any ideas??
Hi Emad,
I think if you have the references of the error page…then you can get the error description, code etc..
Regards,
Shakti
“Hi, nice idea and well done”
I have a need to provide a custom message to users when they attempt to upload a blocked file type. Can this solution be adapted to fit that need? I am unsure if there is an HTML Status code sent with that type of an error or if that is even considered an error. Any help is appreciated.
[...] Access denied Page. Another option is using a control adapter as per Aapo Talvensaari’s post Custom Error Page Adapter although i’d be a little wary implementing the functionality in this manner. My favourite [...]
There are definitely a lot of particulars like that to take into consideration. That is a nice level to carry up. I offer the ideas above as basic inspiration however clearly there are questions just like the one you deliver up the place the most important factor can be working in sincere good faith. I don?t know if greatest practices have emerged around things like that, however I’m certain that your job is clearly identified as a good game. Each boys and girls feel the influence of just a moment’s pleasure, for the rest of their lives.
Normally I do not read post on blogs, however I wish to say that this write-up very compelled me to check out and do it! Your writing taste has been surprised me. Thank you, quite great post.
Hy Aapo, great article. Currently I try to adapt this with SharePoint 2013. The adapter is now working fine for me, but I have to change the compat.browser file manually. I don’t understand how to deploy to APP_Browser folder. Can you described this part again in more detail?
Hi there, for all time i used to check website posts here in the early hours in the daylight,
as i like to learn more and more.
“Why not That’s the dream for every player, to be at big clubs like that, or Bayern Munich.
My favorite hot girls are on krems sex so check them and chat with them for free
Sữa Hikid premium là thành phầm của tập đoàn lớn Ildong Foodis đáng tin tưởng
trên Nước Hàn.
I wish to show thanks to you just for bailing me out of this particular trouble.As a result of checking through the net and meeting techniques that were not productive,
I thought my life was done.
Welcome to Tyler Wagner: Allstate Insurance, your premier insurance
agency based in Las Vegas, NV. Boasting extensive expertise
in the insurance industry, Tyler Wagner and his team are committed to
offering top-notch customer service and comprehensive insurance
solutions.
Whether you’re looking for auto insurance to home insurance,
to life and business insurance, Tyler Wagner: Allstate Insurance
has your back. Our diverse coverage options guarantees that you can find
the perfect policy to meet your needs.
Recognizing the need for risk assessment, our team strives to provide personalized insurance quotes that are tailored to
your specific needs. Through utilizing our expertise in the insurance
market and state-of-the-art underwriting processes, Tyler Wagner ensures that you receive the most competitive premium calculations.
Navigating insurance claims can be a daunting task, but our agency by your side, it’s expert guidance.
Our efficient claims processing system and dedicated customer service team make sure that your claims are
processed efficiently and with the utmost care.
Moreover, we are deeply knowledgeable about insurance law and regulation, guaranteeing that your coverage is consistently in compliance with the latest legal
standards. This expertise provides an added layer of security to our policyholders, knowing that their
insurance policies are robust and dependable.
Our agency, we believe that insurance is more than just a policy.
It’s an essential aspect for safeguarding your future and ensuring the well-being
of those you care about. That’s why, we take the time to understand your individual needs and guide you through the selection of insurance options,
ensuring that you are well-informed and comfortable with your decisions.
Selecting Tyler Wagner: Allstate Insurance signifies partnering with a trusted insurance broker in Las Vegas,
NV, who prioritizes relationships and excellence.
We’re not just your insurance agents; we’re your partners in creating a protected
future.
So, don’t hesitate to reach out today and discover how Tyler Wagner: Allstate Insurance can elevate
your insurance experience in Las Vegas, NV. Experience the difference that comes from having an insurance agency that genuinely cares about your needs and is dedicated to
ensuring your satisfaction.