docs: public void sendError(HttpServletRequest req, HttpServletResponse res, ServletErrorReport error) {
          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
              logger.entering(CLASS_NAME, "sendError", "error :" + error.getMessage());
  
          req.setAttribute("javax.servlet.jsp.jspException", error);
          
          WebContainerRequestState reqState = WebContainerRequestState.getInstance(true);   //PI80786
  
          // PK82794
          if (WCCustomProperties.SUPPRESS_LAST_ZERO_BYTE_PACKAGE)
              reqState.setAttribute("com.ibm.ws.webcontainer.suppresslastzerobytepackage", "true");
          // PK82794
  
          if (!res.isCommitted())
              res.resetBuffer();
  
          String servletName = error.getTargetServletName();
  
          // begin PK04668 IF THE CLIENT THAT MADE THE SERVLET REQUEST GOES
          // DOWN,THERE IS WAS.webcontainer
          Throwable rootCause = error.getRootCause();
          if (rootCause instanceof ClosedConnectionException) {
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                  logger.logp(Level.FINE, CLASS_NAME, "sendError",
                          "sendError occured as a result of ClosedConnectionException. skip sending error page to client");
                  if (rootCause.getCause() != null)
                      logger.logp(Level.FINE, CLASS_NAME, "sendError", "cause of closed connection", rootCause.getCause());
              }
              eventSource.onServletServiceError(new ServletErrorEvent(this, this, servletName, null, error));
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
                  logger.exiting(CLASS_NAME, "sendError", "ClosedConnectionException");
              return;
          } else if (rootCause instanceof javax.servlet.UnavailableException) {
              // end PK04668 IF THE CLIENT THAT MADE THE SERVLET REQUEST GOES
              // DOWN,THERE IS WAS.webcontainer
              // 198256 - begin
              // if (error instanceof WebAppErrorReport)
              // {
              // ((WebAppErrorReport)
              // error).setErrorCode(HttpServletResponse.SC_NOT_FOUND);
              // }
              // 198256 - end
              this.eventSource.onServletServiceDenied(new ServletErrorEvent(this, this, servletName, null, error));
          }
          
          //PI80786 set error code to 400 to avoid logging as 500
          if (SET_400_SC_ON_TOO_MANY_PARENT_DIRS){
              if(reqState.getAttribute("com.ibm.ws.webcontainer.set400") != null) {
                  if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                      logger.logp(Level.FINE, CLASS_NAME, "sendError", "Setting the status code to 400");
                  }
                  error.setErrorCode(HttpServletResponse.SC_BAD_REQUEST);
                  reqState.removeAttribute("com.ibm.ws.webcontainer.set400");
              }
          }
          //PI80786
  
          if (error.getErrorCode() >= 500) {
              if (servletName == null)
                  // Defect 211450
                  logError(error.getUnencodedMessage(), error);
              else {
                  eventSource.onServletServiceError(new ServletErrorEvent(this, this, servletName, null, error));
                  logTrace(error.getUnencodedMessage(), error);
              }
          }
  
          if (req.getAttribute(ServletErrorReport.ATTRIBUTE_NAME) != null) {
              // we are in a recursive situation...report a recursive error
              ServletErrorReport oError = (ServletErrorReport) req.getAttribute(ServletErrorReport.ATTRIBUTE_NAME);
              reportRecursiveError(req, res, oError, error);
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
                  logger.exiting(CLASS_NAME, "sendError", "recursive error");
              return;
          }
  
          // set the error code in the response
          try {
              // if the error code hasn't been set, set it to server error
              if (error.getErrorCode() < 100 || error.getErrorCode() > 599) {
                  error.setErrorCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
              }
  
              // d124698 - set the status code attribute in the request
  
              req.setAttribute(javax.servlet.RequestDispatcher.ERROR_STATUS_CODE, new Integer(error.getErrorCode()));
  
              // set the response status
              res.setStatus(error.getErrorCode());
  
              // We have to determine the charset to use with the error page
              String clientEncoding = req.getCharacterEncoding();
              // PK21127 start
              if (clientEncoding != null && !EncodingUtils.isCharsetSupported(clientEncoding)) {
                  // charset not supported, continue with the logic to determine
                  // the encoding
                  clientEncoding = null;
              }
              // PK21127 end
              if (clientEncoding == null)
                  clientEncoding = com.ibm.wsspi.webcontainer.util.EncodingUtils.getEncodingFromLocale(req.getLocale());
              if (clientEncoding == null)
                  clientEncoding = System.getProperty("default.client.encoding");
              if (clientEncoding == null)
                  clientEncoding = "ISO-8859-1";
  
              res.setContentType("text/html;charset=" + clientEncoding);
          } catch (IllegalStateException ise) {
              // failed to set status code.
              // This could be caused by:
              // 1. the servlet is being included.
              // 2. the stream response is already committed
              com.ibm.wsspi.webcontainer.util.FFDCWrapper.processException(ise, CLASS_NAME + ".handleError", "865", this);
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "WebApp.sendError() failed to set status code.\n"
                                                                   + "This may be caused by a servlet calling response.sendError() "
                                                                   + "while being included or after the response has already been committed to the client.", ise);
          }
  
          // set the exception as an error bean in the response
          req.setAttribute(ServletErrorReport.ATTRIBUTE_NAME, error);
  
          // get this request's error page dispatcher
          RequestDispatcher rd = null;
          try {
              rd = getErrorPageDispatcher(req, error);
          } catch (MajorHandlingRuntimeException e) {
              //If there was a major problem like the application has stopped from under us, we will throw this
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {//306998.15
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "sending sendUnavailableException for context: ["+req.getContextPath()+"]");
              }
              try {
                  WebContainer.sendAppUnavailableException(req, res);
              } catch (IOException e1) {
                  if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {//306998.15
                      logger.logp(Level.FINE, CLASS_NAME, "sendError", "", e);
                  }
              }
              return;
          }
  
          // PK37608 Start
          if (WCCustomProperties.SUPPRESS_WSEP_HEADER) {
  
              Enumeration ViaHeaderValues = req.getHeaders("Via");
  
              if (ViaHeaderValues != null) {
                  boolean foundODRHeader = false;
                  while (!foundODRHeader && ViaHeaderValues.hasMoreElements()) {
  
                      String ViaHeaderValue = (String) ViaHeaderValues.nextElement();
  
                      if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                          logger.logp(Level.FINE, CLASS_NAME, "sendError", "Via Header value : " + ViaHeaderValue);
                      }
  
                      if (ViaHeaderValue.indexOf("On-Demand Router") != -1) {
  
                          foundODRHeader = true;
  
                          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                              logger.logp(Level.FINE, CLASS_NAME, "sendError", "Via Header with On-Demand Router found, add $WSEP header to response.");
                          }
  
                          res.addHeader("$WSEP", "");
  
                      }
                  }
  
                  if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE) && foundODRHeader == false) {
                      logger.logp(Level.FINE, CLASS_NAME, "sendError",
                              "No Via header found with On-Demand Router. Do not add $WSEP header to response.");
                  }
  
              } else if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "No Via Header, do not add $WSEP header to response.");
              }
  
          } else {
  
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "Add $WSEP header to response.");
              }
  
              res.addHeader("$WSEP", "");
          }
          // PK37608 End
  
          try {
              if (rd == null) {
                  //PI09474 Start
                  // PK23428 BEGIN
                  try {
  
                      PrintWriter pw = res.getWriter();
                      if( WCCustomProperties.DISPLAY_TEXT_WHEN_NO_ERROR_PAGE_DEFINED == null) {
                          // PM03788 Start
                          if (WCCustomProperties.SET_UNENCODED_HTML_IN_SENDERROR) {
                              pw.println(error.getUnencodedMessageAsHTML());
                          }
                          else {
                              if (WCCustomProperties.INCLUDE_STACK_IN_DEFAULT_ERROR_PAGE || this.isLocalAddr(req.getRemoteAddr())) {
                                  pw.println(error.getDebugMessageAsHTML());
                              } else {
                                  pw.println(error.getMessageAsHTML());
                              }
                          }// PM03788 End
                      }
                      else {
                          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                              logger.logp(Level.FINE, CLASS_NAME, "sendError", "display custom error text provided in the property");
                          }
                          pw.println(WCCustomProperties.DISPLAY_TEXT_WHEN_NO_ERROR_PAGE_DEFINED);
                      }
                  } catch (IllegalStateException ise) {
                      ServletOutputStream os = res.getOutputStream();
                      reqState.setAttribute("com.ibm.ws.webcontainer.AllowWriteFromE", true); 
                      if( WCCustomProperties.DISPLAY_TEXT_WHEN_NO_ERROR_PAGE_DEFINED == null) {                                             
                          // PM03788 Start
                          if (WCCustomProperties.SET_UNENCODED_HTML_IN_SENDERROR) {
                              os.println(error.getUnencodedMessageAsHTML());
                          }
                          else {
                              os.println(error.getMessageAsHTML());
                          }// PM03788 End
                      }
                      else {
                          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                              logger.logp(Level.FINE, CLASS_NAME, "sendError", "display custom error text provided in the property");
                          }
                          os.println(WCCustomProperties.DISPLAY_TEXT_WHEN_NO_ERROR_PAGE_DEFINED);
                      }
                      reqState.removeAttribute("com.ibm.ws.webcontainer.AllowWriteFromE");
                  }
                  // PK23428 END
                  // PI09474 End
              } else {
                  try {
                      // first attempt to forward (this permits setting of
                      // headers)
                      // res.setStatus(200);
                      rd.forward(req, res);
                      if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
                          logger.exiting(CLASS_NAME, "sendError", "after forward");
                      return;
                  } catch (IllegalStateException ise) {
                      // include the error handler
                      rd.include(req, res);
                      if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
                          logger.exiting(CLASS_NAME, "sendError", "after include");
                      return;
                  }
  
              }
          } catch (Throwable th) {
              com.ibm.wsspi.webcontainer.util.FFDCWrapper.processException(th, CLASS_NAME + ".handleError", "912", this);
              // logger.logp(Level.SEVERE, CLASS_NAME,"sendError",
              // "Error.occurred.while.invoking.error.reporter", new Object[] {
              // error, th });
  
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE)) {
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "Error occurred while invoking error reporter");
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "URL: " + req.getRequestURL());
                  StringWriter sw = new StringWriter();
                  PrintWriter pw = new PrintWriter(sw);
  
                  if (th instanceof ServletException) {
                      DefaultErrorReporter.printFullStackTrace(pw, (ServletException) th);
                  } else {
                      new TruncatableThrowable(th).printStackTrace(pw);
                  }
  
                  pw.flush();
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "Full Exception dump of original error", sw.toString());
                  sw = new StringWriter();
                  pw = new PrintWriter(sw);
                  if (th instanceof ServletException) {
                      DefaultErrorReporter.printFullStackTrace(pw, (ServletException) th);
                  } else {
                      new TruncatableThrowable(th).printStackTrace(pw);
                  }
  
                  pw.flush();
                  logger.logp(Level.FINE, CLASS_NAME, "sendError", "Full Exception dump of recursive error", sw.toString());
              }
  
              reportRecursiveError(req, res, error, new WebAppErrorReport(th));
          }
  
          try {
              // reset the error bean object
              req.setAttribute(ServletErrorReport.ATTRIBUTE_NAME, null);
  
              // 101639 reset the jsp exception object
              req.setAttribute("javax.servlet.jsp.jspException", null);
          } catch (Throwable th) {
              /* ignore */
              com.ibm.wsspi.webcontainer.util.FFDCWrapper.processException(th, CLASS_NAME + ".handleError", "961", this);
          }
          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINE))
              logger.exiting(CLASS_NAME, "sendError");
  
      }