Customize the error page in Domino

Customize the error page in Domino

We get two different types of HTTP 404 Errors returned to the browser, the missing file or the database error.

Customize-the-error-page-in-Domino-22

Cách 1 sử dụng rule trong cấu hình internet site như hình ảnh trên

Reviewed December 2019 for Domino 10. No changes, the configuration is upwards compatible from previous versions.

We get two different types of HTTP 404 Errors returned to the browser, the missing file or the database error.

Before we dig into the details, always keep in mind that the different browser handle errors differently. Not just between Chrome, Firefox, IE and others, a version upgrade may also handle them differently. With this in mind, we look at the Domino configuration to return our own custom message when an error occurs.

The HTTP 404 error message is a standard response when a database or a file was not found. The good thing is that the communication to the server works. Looking at the Domino URL, the 404 error refers to the path including design elements. All the green part is usually considered the file name, example:
http://www.stdi.com/stdi/home.nsf/ws/offroad?openDocument

This error can not be intercepted or redirected with two exceptions.
1. A system wide custom error page can be sent to the browser, but the HTTP 404 Error is still unchanged. This makes sense if you consider web crawlers (yahoo, google etc) that don't want to cache invalid URLs, they depend on the 404 error code.
2. You can also handle the 404 Error in a database by adding the $$ReturnGeneralError forms. Now it is up to the Developer how view and document errors are handled. At this time, I'm not diving any further into this option and concentrate on the system wide error page.

You can however customize the error page that is returned to the browser. It is a configuration option in the browser and may not always produce the expected result.

Example of error handling exception in IE


Some versions of Microsoft Internet Explorer, the 404 error shows a help page that is generated by IE. This is NOT the message returned by the HTTP server or the custom error pages should one exist. IE ignores the custom page and shows it's own help page.


To disable the IE help page, you need to change the Advanced Options in IE as per picture to the right.
Goto > Tools > Internet Options
Open the Advanced Tab
Find Show friendly HTTP error messages
Uncheck the option.

Now you will see the error that is returned from the HTTP server.


Domino Configuration for overwrite
This standard error message can be overwritten on the Domino server.
 


I changed the error page to display the company logo and provide some help regarding the error.
Keep in mind, the 404 Error Code is still returned to the browser, only the page looks different. To accomplish this, you need a file with the HTML code and a NOTES.INI setting that points to the file.


Create a file with the HTML code in it. This example uses a file with the name error.html

<html><head>
<META NAME="DESCRIPTION" CONTENT="Page Not Found">
<title>HTTP 404 Page Not Found</title>
<style type="text/css">
body {font-size:10pt; font-family:sans-serif; background-color:#883366;}
em {font-size:12pt; font-family:sans-serif; font-weight:bold; font-style:italic; color:#c06020; }
A:link { font: bold 12px Arial,sans-serif; color: #0066CC; }
A:visited { font: bold 12px Arial,sans-serif; color: #0066CC; }
A:active { font: bold 12px Arial,sans-serif; color: #0066CC; }
</style>
</head><body>

<div align=center><table border="0" bgcolor="#d0d0d0"><tr valign="top"><td width="780">
<table border=0><TR><TD width="100" align=left>&nbsp;</td>
<td><font color="#000000"><b>Your Company</b></font></td></tr>
</table><table border=0 bgcolor="#FFFFFF"><tr><td width="100" align=left>&nbsp;</td>
<td width="680" align=left><br>
<em>The page you requested is not available.</em><br><br>
Try one of the following:
<li>If you typed the address, verify the correct spelling
<li>If you were referred to this page, go to the <a href="/">home page</a> and navigate to the page.
<br><br><br><br></td></tr></table></td></tr></table></div>

 

The above HTML will produce a page like the one to the right.
Change the colored text to suit your needs and include links to point to more support pages.

The NOTES.INI variable you need to add is:
HTTPMultiErrorPage=/error.html
Copy the error.html file into the Domino/html folder under the Domino data directory.
Note: If you already customized your Domino Web server, the html files may be in a different folder. Check the Web Site documents for the exact location. You could use different pages depending on the website.

Database/Path Configuration for overwrite
The Database Error 404 error message is configured in the domcfg.nsf. If the database doesn't already exist, create a new one called domcfg.nsf in the data directory (use all lowercase). The database must be created from the advance template Domino Web Server Configuration (domcfg5.ntf). The Domino Web Server Configuration database maps the Login, Password and Error Pages. Every configured website can have it's own, unique setup.

To create the error messages, map the individual error to a custom form. The different errors are:

  • General Errors

  • Authentication Failures

  • Authorization Failures

  • Password Expired Errors

  • Password Change Not Allowed Errors

  • Password Change Submitted Responses

  • Document Deleted Responses

    For this document here, the one I'm interested in is the General Errors. It is a bit confusing which error is triggered. The two examples here should shed some light on the mistery.

    Example 1: http://www.stdi.com/notExisting will display the error as per configuration in the NOTES.INI
    Example 2: http://www.stdi.com/notExisting.nsf will display the error as per General Errors configuration in the domcfg.nsf
    Example 3: http://www.stdi.com/stdi/home.nsf/notAview?openView will display the error as per General Errors configuration in the domcfg.nsf
    When the URL looks like a Notes Database as per Example 2, then the domcfg.nsf page is returned.
    And when the database exists, but the view (or document) does not exist, then the same domcfg.nsf page as in #2 is returned.

 

Error pages in Domino another way

 

First of all I'd like to briefly describe few another ways we can use to manage error pages in Domino.

Also notice, I will definitely update post few times more after all.
 
1. Lazy solution $$ReturnGeneralError and MessageString
It's the most fast and easy solutions, it require to create 1 design element (form) $$ReturnGeneralError, style it and add MessageString somewhere to explain what is wrong
Benefits:
- I see only 1 advantage compare to another approaches, its time to implement. Once you create $$ReturnGeneralError it starts to work. So few clicks and few minutes to manage output UI and you have solution.
Disadvantages:
- works inside of application only. So if you have 10 web applications, you need to manage error page in each of it. However you can setup inheritance and manage all error pages from 1 place etc.
- not very flexible on my opinion as we can operate with form-design elements only.
 

2. HTTP response headers

Simply create error page as design element or as document (does not matter) and create rule for your website in Domino Directory database. It does not require special knowledge and it is simple to use.

 

 
 
Benefits:
- easy to manage
- path to Error page (means we can use different database to keep error pages)
- we can use both: Design Elements and Documents as error page.
Disadvantages:
- require minor Administration of Domino skills.
- it works in the same way as client side redirection. i.e. user will see “blink” of standard 404 page before loading custom 404 page.
 
3. "Whole server" solution

Use HTTPMultiErrorPage property in the Notes.ini file, for example HTTPMultiErrorPage=/error.html. Create rule on the Domino server for /error.html to be substituted corresponding page.

Benefits:
Disadvatages:
 
4. DSPAI as error handler for Domino
Most complicated approach but also most flexible from my point of view. There is quite low information about how to use it. It requires knowledge of Notes C Api as well. If you want to see how it looks, here is very good exampe (it helped me a lot) on loggin using DSAPI
Company I worked in use DSAPI for handling URL already, and now we are near to implement error handling using DSAPI as well (it already implemented it on development server, so soon I will show you real links etc).
DSAPI allows us to catch responses Domino generated for users and we can replace output in case if responce 400, 404 or any another.
 
I will post most important part of logic here, just to how overview how DSAPI works and what is gives to us. Notice I've changed code a bit, to show only most important part of it (I will copy comments from Paul's example just to make things faster) 
 
1. initiation of filter and register for response event

/* * FilterInit() - Required filter entry point. Called upon * filter startup, which occurs when HTTP server task is started. */ DLLEXPORT unsigned int FilterInit(FilterInitData* filterInitData) { filterInitData->eventFlags = kFilterResponse; }

so what we did there, say to filter that we want to process response events

2. Link events we registered with functions

/* * HttpFilterProc() - Required filter entry point. Dispatches the event notifications to the appropriate functions for handling the events. */ DLLEXPORT DWORD HttpFilterProc(FilterContext *pContext, DWORD dwEventType, void *pEventData) { switch (dwEventType) { case kFilterResponse: return Response(pContext, pEventData); } return kFilterNotHandled; }

Now we can process Responses to users

3. This is how we process Response to users

int Response(FilterContext* context, FilterResponseHeaders* eventData) { int responce = eventData->responseCode; if (responce==404) { if (Send404(context) == TRUE) { return kFilterHandledRequest; } } return kFilterNotHandled; }

4. Finally code for Send404() how we replace content to users

While you read code you need to know that when we load filter we also initiate a table with KEY-HTML arrays. Yes we keep in memory Error HTML pages with keys we need. Our Keys - domain, we handle error pages on domain level, means for domain1.com - is 1 error page, for domain2.com is another error page. But you can do it in another way its up to you.

int Send404(FilterContext* context) { FilterResponseHeaders response; unsigned int errID = 0; char szBuffer[DEFAULT_BUFFER_SIZE]={0}; char pszErrorPage[ERRRO_PAGE_SIZE]={0}; FilterParsedRequestLine pRequestLine; unsigned int pErrID; int i; // As we are returning the entire page to the browser, we can // set the response code to 404 (so the domino web log will show the error) response.responseCode=404; response.reasonText="Bad Request"; // get domain name (its our key), could be done faster? right now its simple walk via 10-20 documents which is fine for now context->ServerSupport(context, kGetParsedRequest, &pRequestLine, NULL, NULL, &pErrID); for(i=0; i<errorPagesCount;i++) { if (strcmp(errorKey[i], pRequestLine.pHostName)==0) { strcpy(pszErrorPage, errorHTML[i]); i=errorPagesCount; } } if(strlen(pszErrorPage)<10) { sprintf(szBuffer, "Error page on %s is very small, something wrong", pRequestLine.pHostName); writeToLog(CRITICAL_MSG, szBuffer); return FALSE; } sprintf(szBuffer, "Content-Type: text/html; charset=UTF-8\n\nContent-length: %i\n\n", strlen(pszErrorPage)); response.headerText = szBuffer; if (context->ServerSupport(context, kWriteResponseHeaders, &response, 0, 0, &errID) != TRUE) { sprintf(szBuffer, "Error sending redirect, code: %d", errID); writeToLog(CRITICAL_MSG, szBuffer); return FALSE; } if (context->WriteClient(context, pszErrorPage, (unsigned int) strlen(pszErrorPage), 0, &errID) != TRUE) { sprintf(szBuffer, "Error sending redirect, code: %d", errID); writeToLog(CRITICAL_MSG, szBuffer); return FALSE; } return TRUE; }

OK guys, I've shared most complicated part of this DSAPI for error handling, rest you have complete yourself (homework :)), but feel free to ask my help here if you need.

benefits:
- most flexible approach (at least from those which I know)
- our logic control everything we want and we clearly see what is going on
disadvantages:
- most complicated ways from all I described
- require knowledge of Notes C API
- I did not try yet this solution with Linux servers (but I know it is possible to do)
- it may crash your Domino server in case if you did you filter wrong (memory leak etc)

5. xPage error handling is on way (on pause actually) and would be nice if somebody help me with that. I've read few articles in past from Per Henrik: XPages custom 404 and error page and Controlling the HTTP response status code in XPages, I think they can be very useful for those who doing in xPages. We will try this approach as we have ongoing huge projects based on xPage. 

 

Ngày: 8/3/2020 - đăng bởi: Nguyen Van Dat
Nguyen Van Dat 03/08/2020 03:57:49 PM

Tag: #Lập trình Domino IBM



:

----------------