RESTier Submit Logic, push error message to top level - exception

I am using RESTier 0.6.0 library and would like to perform some checks on a resource before deleting it. In the event that the checks fail, I am throwing an Exception to stop the delete operation. However, the error message that I am using to instantiate the Exception is not getting pushed out at the highest level. I can only view the message as an inner exception when serving my Web API from Visual Studio. Is there a way to get this error message to push out at the highest level?
protected void OnDeletingGw_Pack(Gw_Pack pack)
{
var trades = ModelContext.Gw_PackJunction.Where(e => e.PackID == pack.PackID).ToList();
if (pack.Groupage == true || trades.Count > 1)
{
// Don't delete a pack if it is a groupage container or if it's associated with more than one Trade.
throw new Exception("The container you are trying to delete is either marked as groupage or is functioning as a groupage container in another file.");
}
}
Currently any Exception thrown within the OnDelete submit logic methods in the EntityFrameworkApi results in an error which looks like this:
{
"error":{
"code":"","message":"An error has occurred."
}
}
... which is not particularly useful to the client.
UPDATE: I noted in the RESTier documentation MkDocs version that an example was given where an ODataException (rather than Exception) was thrown. I changed this in my code, but the error object returned by the published Restier service still only has the basic "An error has occurred" information.
Assistance is greatly appreciated!

When throwing an Exception within the RESTier EntityFrameworkApi (inside and OnUpdate<EntitySet> method for example), the exception is deserialized as part of the inner exception (internalexception). So in order to view any exceptions thrown within the RESTier API, one needs to...
set the IncludeErrorDetailPolicy property on the HttpConfiguration
class like this:
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
Structure of error received by client
See this post: OData controller returns different error for local and different for remote machine

Related

custom exception message in spring cloud function deployed in aws-lambda

I have a java project written using spring-cloud-function and deployed in aws-lambda.
I am trying to return a custom exception with some fields in the exception message body, something like"
{
reason: <exception reason>
code: <error code>
<some other fields>
}
#ExceptionHandler, that is generally used in spring boot doesn't seem to work here.
I can return the exception in the required format by creating a class for building the exception message in required format but in that case the error code will always be 200 since it will not be an exception object per se. Instead it will be my custom error object.
Is there a way I can set this up so that the above required format of exception object is returned and correct error code can be returned too?
Thanks in advance
First, the exception has nothing to do with Spring Boot. It's part of spring-web, so yes it would not work here since s-c-function is a general purpose framework, where the same function could be deployed and triggered via web, streaming, aws-lambda etc. .
Now, yes we had a problem returning JSON error (as you show) or object that represents the same, but that was fixed. So please update s-c-function to 3.2.3.

Actual exception is not getting logged in MVC when host in IIS

I am running one MVC application where i found one exception in specific method. I will provide here complete details about it.
I am loading some third party grid control from view. to load it i used below code:
#{Html.RenderAction("MasterGridAction", "MyController");}
Now when i access this report from development then this view load and it hits this action method where i used some piece of code there it is throwing error, To catch the error i used try catch block in the method where in catch section i used below code to throw the actual exception like below:
catch (Exception ex)
{
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw(); throw;
}
When exception get catched it sends this to the Application_Error method in global.asax page where i used below code to find out the actual exception like below:
void Application_Error(object sender, EventArgs e)
{
HttpServerUtility server = HttpContext.Current.Server;
if (server.GetLastError() != null)
{
Exception exception = server.GetLastError();
if (exception.GetBaseException() != null)
{
exception = exception.GetBaseException();
ExceptionType(server, exception);
}
else
{
ExceptionType(server, exception);
}
}
}
In this ExceptionType method i get the exception stack and log to the file using "Log4Net". After logging to the file i could see the exception in notepad like below:
Object reference not set to an instance of an object.
Source File: /MyController/MasterGridAction
Stack Trace:
at 3D.Controllers.MyController.MasterGridAction() in D:\MyUser\3D_MVC\Application\3D_OnlyRelease\3D\Controllers\MyController.cs:line 405
--- End of stack trace from previous location where exception was thrown ---
As we can see in above exception it is clearly shown the line number also where this exception get caught.
But once i host this application in IIS server and access the same page then i could see the logged file
There it shows exception like below:
Exception Message: Object reference not set to an instance of an object.
Stack Trace: at 3D.Controllers.MyController.MasterGridAction()
--- End of stack trace from previous location where exception was thrown ---
As you can see the logged exception of IIS server is not having much information when compare to other exception details.
Am i missing anything there to get the complete exception when host in IIS?
Please suggest.
As you can see the logged exception of IIS server is not having much information when compare to other exception details.
This could be because you don't include the PDB files in production.
It might not be a great idea to include them, since that way one can reverse engineer you app with more precision if they hack your server, but it is up to you to decide. I have seen organizations that include them in their production environments.
Try publishing and deploying on a test environment with and without the PDB files to verify this.

The noticeError method was not found. while using Coldbox and NewRelic for Error tracking

I'm just using NewRelic error trapping for my coldbox application. From OnException method, I'm just sending the error struct to log the error.
My code in onexception method
public function onException(event,rc,prc){
NewRelic.logError( prc.exception.getExceptionStruct());
}
The logerror() method resides in NewRelic.cfc and contains the following code
public boolean function logError(
required struct exception
) {
var cause = arguments.exception;
var params = {
error_id = createUUID(),
type: arguments.exception.type,
message: arguments.exception.message
};
writeDump(this.newRelic);
this.newRelic.noticeError(cause, params);abort;
return true;
}
So while error, I'm gettig the following error.
The noticeError method was not found.
You can see that, the noticeError() method is there in the object, but it is overloaded with arguments.
I'm using the same code for NewRelic error trapping in another coldfusion project without any frameworks.
Calling error.cfm through Cferror tag, and the code in error.cfm as follows
<cfset Application.newRelic.logError( variables.error )>
And in NewRelic.cfc, the logerror() method contains the same code as in the coldbox application. But it is logging errors in NewRelic without any issues.
This is the method I need to notice errors and log it in NewRelic.
noticeError(java.lang.Throwable, java.util.Map)
So I just thought to get the classname of the first argument Cause through the following code from both applications within logError() in NewRelic.cfc, to get the difference.
writeDump(cause.getClass().getName());
I'm getting
coldfusion.runtime.ExceptionScope for Coldbox application
and
coldfusion.runtime.UndefinedVariableException for normal coldfusion application
The cause argument is not throwable from coldbox application. So how to get the original error struct from coldbox application? and make it throwable to fix the noticeError method was not found issue.
The change in the underlying class happens when ColdBox duplicates the error object with CFML's duplicate() method. I doubt that ColdFusion behavior is documented anywhere, but I don't see an easy way to get around it right now other than creating your own instance of a java.langException and populating it with the details of the original error.
If you want to modify the ColdBox core code, this happens here:
https://github.com/ColdBox/coldbox-platform/blob/master/system/web/context/ExceptionBean.cfc#L43
I have entered this ticket for the ColdBox framework for us to review if we can stop duplicating the error object in future versions of the framework.
https://ortussolutions.atlassian.net/browse/COLDBOX-476
Update: Adam Cameron pointed out this ticket in the Adobe bug tracker that details this behavior in the engine. It was closed as "neverFix".
https://bugbase.adobe.com/index.cfm?event=bug&id=3976478

Breeze EF6 SaveChanges doesn't propagate exceptions

In the EFContextProvider (EF6) SaveChangesCore method, the exception handling looks like this:
} catch (Exception e) {
while (e.InnerException != null) {
e = e.InnerException;
}
throw e;
}
This throws only the most internal exception and hides the relevant information revealed by the external exceptions.
When the SaveChanges process goes through multiple layers the next direct layer exception is lost, and only the last exception in the chain is thrown. It doesn't allow to handle well the exceptions for the caller.
Updated Post
As of Breeze 1.4.6, any .NET Exceptions thrown on the server are now available in their original form in the httpResponse.data property of any async breeze result. Breeze will still drill down to extract a "good" error message, but will no longer obscure the initial exception.
Original Post Below -------------------
It's an interesting point. The reason we did this was because most client side apps aren't written to navigate thru the exception chain and we wanted to expose the most 'relevant' error to the client. Most of the apps we looked at just exposed the client "error.message" property directly and with EF errors this was almost always useless.
However, your point is well taken. I think what we need to do is create a new Exception that has a top level message that is the innermost exception message but still expose the entire exception chain for those that want to drill. I've added an internal feature request for this and will try to get it into a near term release ( probably not the next one because we are already in testing for that one).
And thanks for the input.

How to return stack Trace to Client in MULE..?

Does anybody know how to print full stack trace on the Browser, when a Runtime Exception occurs in MULE..??
When a runtime Exception occurs, MULE throws a 500 Server Error to the client , but shows no details to the client. It prints the whole stack trace in Console or Log Files (like the following) :
Root Exception stack trace:
java.sql.SQLException: Invalid column name
at oracle.jdbc.driver.OracleStatement.getColumnIndex(OracleStatement.java:3677)
at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:2749)
at oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:494)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true'
for everything)
Can i show the same stack Trace on the Browser (to the client)..??
And if possible , then also tell me how to switch ON or OFF printing of Stack Trace on Browser..??
(It may be possible that sometime in future , i dont want to show stack trace on browser)
Yes this is possible. I assume you are using a regular HTTP endpoint and this is a REST type service(?) If so, you can simply put a try/catch around the code causing the exception and return whatever text you want.
There are also exception strategies (http://www.mulesoft.org/documentation/display/MULE3USER/Error+Handling) for doing more sophisticated error handling, but it sounds like you are looking for the simple answer above.
If this doesn't answer your question, please provide more info about your mule config and the service that is raising the exception.
There is nothing out of the box in Mule to do that. You have to implement an exception handler that will format the stacktrace in the Message exception payload and return it to the caller.
In your case, the HTTP transport has a particularity that can be found in the HttpMessageReceiver code:
try
{
conn.writeResponse(processRequest(request));
}
catch (Exception e)
{
...
conn.writeResponse(buildFailureResponse(request.getRequestLine().getHttpVersion(), httpStatus, e.getMessage()));
This means that when an exception crops-up to the top level, the creation of the failure message response is not customizable: you get this pretty technical message back and that is all.
I see two options to solve your problem:
sub-class HttpMessageReceiver and make the response message customizable in your version,
drop the HTTP transport in favor of the Jetty one (look at the bookstore example) and customize the response error messages at the web container level.