How to display a generic error page in Asp.Net MVC 2 - asp.net-mvc-2

I have the following in my base controller:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
// If custom errors are disabled, we need to let the normal ASP.NET exception handler
// execute so that the user can see useful debugging information.
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
Exception exception = filterContext.Exception;
// If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
// ignore it.
if (new HttpException(null, exception).GetHttpCode() != 500)
{
return;
}
// TODO: What is the namespace for ExceptionType?
//if (!ExceptionType.IsInstanceOfType(exception))
//{
// return;
//}
// Send Email
MailException(exception);
// TODO: What does this line do?
base.OnException(filterContext);
filterContext.Result = new ViewResult
{
ViewName = "Error"
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
}
In my Shared folder, I have an Error.aspx View.
Web.config
<customErrors mode="On" />
I am still seeing the yellow screen when an exception occurs. What am I doing incorrectly?

I would imagine that invoking base.OnException handler is what is causing your problem. Without actually looking at the code, I would imagine that it is what is responsible for handling the error and generating a response with the exception and stack trace. Remove that line from your code -- it's not needed as since you're replacing the ViewResult anyway.
I would recommend that you use ELMAH and implement a HandleError attribute that works with it: see this question. ELMAH is very flexible and configuration driven, rather than code driven.

Server.ClearError()
What happens if you call that?

Related

Apache Camel REST DSL - Validating Request Payload and return error response

I am exposing a rest service using "CamelHttpTransportServlet" that receive orders and place in jms queue. The code works fine on happy path and returns 200 response.
I have written Processor to validate the input JSON, and set http_response_code based on the input.
The issue is - for invalid requests though failure response code - 400 is set, the flow continues to the next route and pushes the data to the queue instead of sending the 400 response back to the calling app.
rest("/ordermanagement")
.post("/order").to("direct:checkInput");
from("direct:checkInput")
.process(new Processor() {
#Override
public void process(final Exchange exchange) throws Exception {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == "" || requestBody== null) {
exchange.getIn().setBody("{ "error": Bad Request}");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
}
}
})
.to("direct:sendToQ");
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
Can someone advise what is missing here and provide a sample if possible?
Trying to implement onException approach:
rest("/ordermanagement")
.post("/order").to("direct:checkInput");
onException(CustomException.class).handled(true)
.setHeader(Exchange.HTTP_RESPONSE_CODE, code)
.setBody(jsonObject);
from("direct:checkInput")
.process(new Processor() {
#Override
public void process(final Exchange exchange) throws Exception {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == "" || requestBody== null) {
throw CustomException(code, jsonObject)
}
}
})
.to("direct:sendToQ");
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
However I could not figure out how to pass the parameters - code,jsonObject from processor to onException block.
Any help on this? Is this feasible?
I'd use something along the lines of the code example below:
onException(CustomException.class)
.handled(true)
.bean(PrepareErrorResponse.class)
.log("Error response processed");
rest("/ordermanagement")
.post("/order")
.to("direct:checkInput");
from("direct:checkInput")
.process((Exchange exchange) -> {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == "" || requestBody== null) {
throw new CustomException(code, jsonObject);
}
})
.to("direct:sendToQ");
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
Camel will store any exception caught in the exchange's property and should be therefore obtainable via the Exchange.EXCEPTION_CAUGHT property key. The sample below illustrates how such a custom error message bean can look like:
public class PrepareErrorResponse {
#Handler
public void prepareErrorResponse(Exchange exchange) {
Throwable cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
if (cause instanceof CustomException) {
CustomException validationEx = (CustomException) cause;
// ...
}
Message msg = exchange.getOut();
msg.setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
msg.setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
JsonObject errorMessage = new JsonObject();
errorMessage.put("error", "Bad Request");
errorMessage.put("reason", cause.getMessage());
msg.setBody(errorMessage.toString());
// we need to do the fault=false below in order to prevent a
// HTTP 500 error code from being returned
msg.setFault(false);
}
}
Camel provides a couple of ways actually to deal with exceptions. The presented way here is just one example. The proposed code however allows to use custom redelivery strategies for different caught exceptions as well as additional stuff. If the error could get resolved within the exception handler, the route is proceeded at the point the exception occurred (i.e. temporary network issue with a redelivery strategy applied). If the error could not get fixed within the handler, the exchange will be stopped. Usually one would then send the currently processed message to a DLQ and log something about the error.
Note that this example will assume that CustomException is an unchecked exception as the processor is replaced with a simpler lambda. If you can't or don't want to use such an exception (or lambda expressions) replace the lambda-processor with new Processor() { #Override public void process(Exchange exchange) throws Exception { ... } } construct.
Here is one way to do it. You can use choice
rest("/ordermanagement")
.post("/order").to("direct:checkInput");
from("direct:checkInput")
.process(exchange -> {
String requestBody = exchange.getIn().getBody(String.class);
if(requestBody == null || requestBody.equals("")) {
exchange.getIn().setBody("{ "error": Bad Request}");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
}
})
.choice()
.when(exchange -> {
Object header = exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE);
return header != null && header.equals(400);
})
.stop()
.otherwise()
.to("direct:sendToQ")
.endChoice();
from("direct:sendToQ")
.to("jms:queue:orderReceiver")
.log("Sent to JMS");
Setting ROUTE_STOP property to true in the processor should prevent further flow and return your response:
...
exchange.getIn().setBody("{ "error": Bad Request}");
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, "application/json");
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
...

Eclipse plugin - getting the IStackframe object from a selection in DebugView

So, this is the problem I am stuck at for a few weeks.
I am developing an Eclipse plugin which fills in a View with custom values depending on a particular StackFrame selection in the Debug View.
In particular, I want to listen to the stackframe selected and would like to get the underlying IStackFrame object.
However, I have tried more than a dozen things and all of them have failed. So I tried adding DebugContextListener to get the DebugContextEvent and finally the selection. However, the main issue is that ISelection doesn't return the underlying IStackFrame object. It instead returns an object of type AbstractDMVMNode.DMVMContext. I tried getting an adapter but that didn't work out too. I posted this question sometime back also:
Eclipse Plugin Dev- Extracting IStackFrame object from selection in Debug View
Since then, I have tried out many different approaches. I tried adding IDebugEventSetListener (but this failed as it cannot identify stack frame selection in the debug view).
I tried adding an object contribution action but this too was pointless as it ultimately returned me an ISelection which is useless as it only returns me an object of class AbstractDMVMNode.DMVMContext and not IStackframe.
Moreover, I checked out the implementation of the VariablesView source code itself in the org.eclipse.debug.ui plugin. It looks like a few versions back (VariablesView source code in version 3.2), the underlying logic was to use the ISelection and get the IStackFrame. All the other resources on the internet also advocate the same. However, now, this scheme no longer works as ISelection doesn't return you an IStackFrame. Also, the source code for the latest eclipse Debug plugin (which doesn't use this scheme) was not very intuitive for me.
Can anyone tell how I should proceed ? Is hacking the latest Eclipse source code for VariablesView my only option ? This doesn't look like a good design practice and I believe there should be a much more elegant way of doing this.
PS: I have tried all the techniques and all of them return an ISelection. So, if your approach too return the same thing, then it is most likely incorrect.
Edit (Code snippet for trying to adapt the ISelection):
// Following is the listener implemnetation
IDebugContextListener flistener = new IDebugContextListener() {
#Override
public void debugContextChanged(DebugContextEvent event) {
if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
contextActivated(event.getContext());
}
};
};
// Few things I tried in the contextActivated Method
//Attempt 1 (Getting the Adapter):
private void contextActivated(ISelection context) {
if (context instanceof StructuredSelection) {
Object data = ((StructuredSelection) context).getFirstElement();
if( data instanceof IAdaptable){
System.out.println("check1");
IStackFrame model = (IStackFrame)((IAdaptable)data).getAdapter(IStackFrame.class);
if(model != null){
System.out.println("success" + model.getName());
}
}
}
}
// Attemp2 (Directly getting it from ISelection):
private void contextActivated(ISelection context) {
if (context instanceof StructuredSelection) {
System.out.println("a");
Object data = ((StructuredSelection) context).getFirstElement();
if (data instanceof IStackFrame) {
System.out.println("yes");
} else {
System.out.println("no" + data.getClass().getName());
}
}
// This always execute the else and it prints: org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode.DMVMContext
}
// Attemp3 (Trying to obtain it from the viewer (similiar to object action binding in some ways):
private void contextActivated(ISelection context) {
VariablesView variablesView = (VariablesView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_VARIABLE_VIEW);
if (variablesView != null) {
Object input = ((TreeViewer) variablesView.getViewer()).getInput();
if(input != null) System.out.println(input.getClass().getName());
if (input instanceof IStackFrame) {
System.out.println("success");
} else if (input instanceof IThread) {
System.out.println("success");
try {
IStackFrame[] stackFrames = ((IThread) input).getStackFrames();
for (IStackFrame iStackFrame : stackFrames) {
printVariables(iStackFrame);
}
} catch (DebugException e) {
e.printStackTrace();
}
}
}
}
While I am building this view to work with both JDT & CDT, I am testing it out on the C project. So, this might be the reason why I always get the returned object type as AbstractDMVMNode.DMVMContext. Should my implementation be different to handle both these cases ? I believe I should be building a generic view. Also, if AbstractDMVMNode.DMVMContext is CDT specific, I should I go about implementing it for the CDT case?

Set Active User to AEM background job throws Exception unexpectedly

We have background job running that requires a user to be active. The following way works fine but we have to hard-code the password which is not ideal.
try {
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
} catch (RepositoryException ex) {
log.error("SessionHelper - login issue", ex);
}
We attempt a better way to set active user without setting password as follows:
Map<String, Object> params = new HashMap<String, Object>();
params.put(ResourceResolverFactory.SUBSERVICE, "theService");
ResourceResolver resolver = null;
try {
resolver = resolverFactory.getServiceResourceResolver(params);
} catch (LoginException e) {
log.error("LoginException", e);
}
Session session = resolver.adaptTo(Session.class);
// Next, create pages and add properties ...
We then try to create pages and set properties. This works fine for couple of milliseconds where some pages are created but then throws Exception to indicate session is closed although never closed and the location where exception gets thrown is unpredictable.
javax.jcr.RepositoryException: This session has been closed. See the chained exception for a trace of where the session was closed.
...
Caused by: java.lang.Exception: Stack trace of where session-admin-20077 was originally closed
We want to know whether there is any way to set the timeout? Any recommendations appreciated.
You should obtain the session always through the ResourceResolverFactory using the getServiceResourceResolver method (getAdministrativeResourceResolver method is actually deprecated and should be avoided), execute than your code in the same try/catch block and define a finally block where you can make sure that the obtained resolver/session is closed properly. If you follow this princip, you will probably never experience problems with closed or unclosed sessions.
#org.apache.felix.scr.annotations.Component(...)
public class MyComponent {
#org.apache.felix.scr.annotations.Reference
private org.apache.sling.api.resource.ResourceResolverFactory resourceResolverFactory;
public void myaction() {
org.apache.sling.api.resource.ResourceResolver resolver = null;
try {
Map<String, Object> authInfo = new HashMap<String, Object>();
authInfo.put(ResourceResolverFactory.SUBSERVICE, getClass.getName());
resolver = resourceResolverFactory.getServiceResourceResolver(authInfo);
javax.jcr.Session session = resolver.adaptTo(javax.jcr.Session.class);
javax.jcr.Node node = session.getNode("/jcr/path/to/the-node");
// do something with the node
session.save();
} catch(LoginException e) {
// Handle cannot obtain instance of the resource resolver
} catch(RepositoryException e) {
//handle the repository exception
} finally {
//do not forget to close the resolver, otherwise this can cause huge performance problems
if(resolver != null) {
resolver.close();
}
}
}
}
In order to obtain service resource resolver, you need also to configure the user.mapping in the OSGI-Service org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl for example as follows.:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
user.mapping="[tld.mycompany.mypackage=admin]"
user.default="admin"/>
This way you can set and offer very advanced access control policies for your services.
If you are in a sling servlet, be carefull which resource resolver you are using. In the normal case, you will not need a resource resolver with administrative rights, but take the one provided by the SlingHttpServletRequest. The resource resolver is closed by sling at the end of the request, don't close it manually.
If you are using the admin session I suggest to not log it in like you did, but with the following method (asuming from your code you have the SlingRepository already injected with #Reference):
repository.loginAdministrative(null);
And to prevent the error I would use the following pattern:
Session session = null;
try {
session = repository.loginAdministrative(null);
//do what you need to do
} catch (RepositoryException e) {
//handle exception
} finally {
if (session != null && session.isLive()) {
session.logout();
}
}
And one last note, open and close the sessionin the same thread, so not keeping the session alive in a service, except it is an EventListener.

Nodejs: How to catch exception in net.createServer.on("data",...)?

I've got a standard socket-server (NO HTTP) setup as follows (contrived):
var server = net.createServer(function(c) { //'connection' listener
c.on('data', function(data) {
//do stuff here
//some stuff can result in an exception that isn't caught anywhere downstream,
//so it bubbles up. I try to catch it here.
//this is the same problem as just trying to catch this:
throw new Error("catch me if you can");
});
}).listen(8124, function() { //'listening' listener
console.log('socket server started on port 8124,');
});
Now the thing is I've got some code throwing errors that aren't catched at all, crashing the server. As a last measure I'd like to catch them on this level, but anything I've tried fails.
server.on("error",....)
c.on("error",...)
Perhaps I need to get to the socket instead of c (the connection), although I'm not sure how.
I'm on Node 0.6.9
Thanks.
process.on('uncaughtException',function(err){
console.log('something terrible happened..')
})
You should catch the Exceptions yourself. There is no event on either connection or server objects which would allow you to handle exception the way you described. You should add exception handling logic into your event handlers to avoid server crash like this:
c.on('data', function(data) {
try {
// even handling code
}
catch(exception) {
// exception handling code
}

GWT: Continue editing the same object after request to server

Is it possible to continue editing the same object after GWT server request?
Consider best-practices code from another question
void start() {
// Either get p
context1.get(..).to( new Receiver<P> { onSuccess(P resp){p = resp;} ... }).fire();
// OR create p
p = context2.create( P.class );
// Then save p
req = context2.persist(p).to( new Receiver<P>{ /* note do not use context1 */
onViolation(...) { /*JSR 303 handler*/ };
onFailure( error ) { /* handle */ error.getMessage() };
onSuccess(X x) { /* whatever persist() returns handler */ }; } );
// drive editor with p
driver.edit( p, req);
}
....
void onSave() {
// editor
ctxt = driver.flush() /* note ctxt == context2 */
if ( driver.hasErrors() ) { /*JSR 303 handler*/};
// RF
ctxt.fire();
}
The question is, how to handle un-successful server response in the last line? (add receiver to "ctxt.fire();")
void onSave() {
// editor
ctxt = driver.flush() /* note ctxt == context2 */
if ( driver.hasErrors() ) { /*JSR 303 handler*/};
// RF
ctxt.fire(new Receiver<S>{
onSuccess() { ... how to continue editing the "p" object? ... }
onFailure() { ... how to continue editing the "p" object? ... } });
});
}
For example, on save, sever does some additional validation (e.g. that value is unique). And does not accept to save it.
So, server request finishes with "onSuccess(response)" method, but object was not saved (response value may contain list of errors).
Is it possible to allow user to continue editing the unsaved, but updated on client side object and make another request to the server?
The "deadlock" that I see:
It is not possible to reuse request context (ctxt), because "A request is already in progress" exception will be thrown.
It is not possible to create a new context, because all modifications to the object are in the old context (so they will be lost).
Mutable proxies are always bound to a request context. Proxies you receive from the server, however, are frozen and not mutable. The .edit method will make a mutable clone of a frozen proxy for a given request context.
If a request couldn't be fired (connection issues, server error), the context will be re-usable and you can continue editing the proxy. Same applies if the constraints were violated.
If a request was successfully fired (no matter if the server method threw an exception or not), the request context cannot be used no more and the same applies to the proxy.
Have a look at onTransportSuccess in AbstractRequestContext - this will tell you: the only cases in which you can continue using the request context are violation and general failure. So either you enforce a violation or you return (the erroneous) object to the client and continue working on it with a fresh request context (this will lead to issues with entity proxies I'm afraid since it will loose the reference state)