In my logs, I found a weird error regarding my ServiceStack service. I don't have further information than the following stacktrace and I didn't manage to reproduce the error yet. That's the stacktrace:
JsvTypeSerializer.EatMapKey (ServiceStack.Text.StringSegment value, System.Int32& i)
DeserializeDictionary`1[TSerializer].ParseStringDictionary (ServiceStack.Text.StringSegment value)
(wrapper delegate-invoke) :invoke_object_StringSegment (ServiceStack.Text.StringSegment)
JsvReader`1[T].ParseStringSegment (ServiceStack.Text.StringSegment value)
JsvReader`1[T].Parse (System.String value)
TypeSerializer.DeserializeFromString[T] (System.String value)
StringExtensions.FromJsv[T] (System.String jsv)
WebServiceException.ParseResponseDto ()
WebServiceException.get_ErrorMessage ()
WebServiceException.get_Message ()
I'm not sure where I should start, the service actually only has json enabled and not jsv, and the part where I handle the request is inside a try-catch block, so I'm not sure why the error is actually happening.
This Exception is due to not being able to parse a structured Error ResponseStatus thrown in a WebServiceException possibly due to returning an unknown Error Response. I've made it so this parsing heuristic doesn't throw an Exception when it fails in this commit.
This change is available from v5.0.3 that's now available on MyGet.
Related
I have following code
IAsyncOperation<bool> trythiswork()
{
bool contentFound{ false };
try
{
auto result = co_await someAsyncFunc();
winrt::check_bool(result)
if (result)
{
contentFound = true;
}
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
}
co_return contentFound;
}
When the result is false, it fails and throws but catch goes to fail fast and program terminates. How does log function terminate the program? Isn't it supposed to only log the exception? I assumed that I am handling this exception so program won't crash but it is crashing.
So how to throw and catch so that program does not terminate? I do want to throw. And also catch and preferably log the exception as well.
Thanks
The issue can be reproduced using the following code:
IAsyncOperation<bool> someAsyncFunc() { co_return false; }
IAsyncOperation<bool> trythiswork()
{
auto contentFound { false };
try
{
auto result = co_await someAsyncFunc();
winrt::check_bool(result);
// throw std::bad_alloc {};
contentFound = true;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
}
co_return contentFound;
}
int main()
{
init_apartment();
auto result = trythiswork().get();
}
As it turns out, everything works as advertised, even if not as intended. When running the code with a debugger attached you will see the following debug output:
The exception %s (0x [trythiswork]
Not very helpful, but it shows that logging itself works. This is followed up by something like
FailFast(1) tid(b230) 8007023E {Application Error}
causing the process to terminate. The WIL only recognizes exceptions of type std::exception, wil::ResultException, and Platform::Exception^. When it handles an unrecognized exception type it will terminate the process by default. This can be verified by commenting out the call to check_bool and instead throwing a standard exception (such as std::bad_alloc). This produces a program that will log exception details, but continue to execute.
The behavior can be customized by registering a callback for custom exception types, giving clients control over translating between custom exception types and HRESULT values. This is useful in cases where WIL needs to interoperate with external library code that uses its own exception types.
For C++/WinRT exception types (based on hresult_error) the WIL already provides error handling helpers that can be enabled (see Integrating with C++/WinRT). To opt into this all you need to do is to #include <wil/cppwinrt.h> before any C++/WinRT headers. When using precompiled headers that's where the #include directive should go.
With that change, the program now works as desired: It logs exception information for exceptions that originate from C++/WinRT, and continues to execute after the exception has been handled.
In a native-C++-Dll (MFC): how to throw an Exception (with some additional text) that can be catched and handled from a .NET-Client?
This is the native-MFC-Dll which wants to throw an Exception:
void RGaugeTVDDataReader::LoadDataFromFile_HandleException(const CString& szPath) const
{
CString sMessage;
sMessage.Format(_T("TVD-File %s"), static_cast<LPCTSTR>(szPath));
/*1*/ AfxThrowFileException(CFileException::genericException, -1, static_cast<LPCTSTR>(sMessage));
/*2*/ throw std::runtime_error(CT2A(sMessage));
}
The Caller is a .Net-Dll which uses the native dll via a .net-generated-COM-Wrapper.
Both variants (/1/ and /2/) fall into the catch-Block of the .Net-Component but what I get here is just a ´System.Runtime.InteropServices.SEHException´ and the exceptionmessage says "External component has thrown an exception.". Included ErrorCode and HResult is 0x80004005. There is no inner exception, nothing to find about my given text and the stacktrace only contains the managed part.
So the question is: how to throw an excpetion from the native-c++-dll so that a .net-client using it via COM can at least see the message-string?
Alternative question: how to catch and handle the thrown exception in .net correctly?
regards
mSubscriptions.add(api.signIn(phoneNumber, otp)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Timber.e(throwable.getMessage()))
.onErrorResumeNext(throwable -> Observable.empty())
.subscribe(user -> {
// Handle user object logic here
}
}));
I generally use this pattern in all my apps for the schedulers and to handle exceptions, but sometimes i get an illegal state exceptions like this : Exception thrown on Scheduler.Worker thread. Add onError handling. Caused by rx.exceptions.OnErrorNotImplementedException, so i was wondering if this is right.
Thanks in advance.
As #yosriz mentioned - the right way is to implement onError callback in every subscriber. In your case, you're getting OnErrorNotImplementedException most likely due to your "Handle user object logic" throws.
Simple examples:
Exception in the stream:
Observable.just("value")
.flatMap(s -> Observable.error(new IllegalStateException()))
.onErrorResumeNext(t -> Observable.empty())
.doOnCompleted(() -> System.out.println("Completed"))
.subscribe(s -> {});
Completed
Exception in onNext callback:
Observable.just("value")
.onErrorResumeNext(t -> Observable.empty())
.doOnCompleted(() -> System.out.println("Completed"))
.subscribe(s -> {
throw new IllegalStateException();
});
rx.exceptions.OnErrorNotImplementedException
...
Caused by: java.lang.IllegalStateException
Exception in onNext callback, subscriber's onError implemented:
Observable.just("value")
.onErrorResumeNext(t -> Observable.empty())
.doOnCompleted(() -> System.out.println("Completed"))
.subscribe(s -> {
throw new IllegalStateException();
}, t -> {
System.out.println("Subscriber's onError triggered");
});
Subscriber's onError triggered
Arranging Schedulers has nothing to do with this type of error you get. The problem can happen if you don't have onError() handling on your subscriber (at the subscribe() method), and you get error somewhere in the stream without any handling.
doOnError() will not solve this, as it's just a side effect operator that will perform some operation with any onError().
In fact, In your example onErrorResumeNext() will handle the error as it will swallow any error, so probably you have other scenarios, where you do not handle all errors scenarios and thus got the on error not implemented exception.
As a general pattern, it's always better to prepared to any case and implement onError() at the subscriber to avoid cases where error was not handled down the stream.
I have a very specific question, and i really searched the answer all over the place...
Here is a situation: i have a Scatter-Gather component with a custom aggregation strategy.
http://clip2net.com/s/j66jK8 - Image of a subflow
Semantic of this process is rather simple. Request comes with Basic Authentication Header, the upper road calls just empty java processor, which returns original payload, the lower road authenticates user over LDAP, and returns Boolean result of this authentication process. Custom aggregation class checks result and if authentication was OK, then returns original payload, which results from the road #1. If not OK, then throws exception. Nothing wrong here, it works.
There is a bit tricky thing. If a user passed wrong authentication data then exception occurs in ldap:bind module. According to documentation exception is propagated to the Scatter-Gather so i'm trying to catch it using this:
#Override
public MuleEvent aggregate(AggregationContext context) throws MuleException {
for (MuleEvent event: context.collectEventsWithExceptions()) {
event.getMessage().getExceptionPayload().getException().printStackTrace();
throw new RuntimeException(event.getMessage().getExceptionPayload().getException());
}
MuleEvent result = DefaultMuleEvent.copy(context.getEvents().get(0));
if (!(Boolean) context.getEvents().get(1).getMessage().getPayload()) {
throw new SecurityException();
}
return result;
}
BUT!
As a result i see exception which stacktrace does not have javax.naming.AuthenticationException which was rased by ldap:bind component, and was printed to log automaticaly (see below).
So, my question is: how can i reach and rethrow this javax.naming.AuthenticationException exception out of Custom Aggregation Class?
I'd appreciate all you ideas and help. Thank you in advance.
WARN 2014-10-15 20:51:18,552 [[minkult].ScatterGatherWorkManager.02] org.mule.module.ldap.api.jndi.LDAPJNDIConnection: Bind failed.
ERROR 2014-10-15 20:51:18,559 [[minkult].ScatterGatherWorkManager.02] org.mule.retry.notifiers.ConnectNotifier: Failed to connect/reconnect: Work Descriptor. Root Exception was: javax.naming.AuthenticationException: [LDAP: error code 49 - INVALID_CREDENTIALS: Bind failed: Attempt to lookup non-existant entry: cn=sim,ou=people,dc=example,dc=com]; resolved object com.sun.jndi.ldap.LdapCtx#5de37d66. Type: class javax.naming.AuthenticationException
COUNT: 1
org.mule.api.transport.DispatchException: route number 1 failed to be executed. Failed to route event via endpoint: InterceptingChainLifecycleWrapper 'wrapper for processor chain 'null''
[
ScriptComponent{CheckAuth.component.553657235},
org.mule.module.ldap.processors.BindMessageProcessor#647af13d,
org.mule.module.ldap.processors.SearchMessageProcessor#2aac6fa7,
InvokerMessageProcessor [name=ldapUtils, object=com.at.mkrf.aggregate.LDAPUtils#5714c7da, methodName=findGroupByName, argExpressions=[#[payload], #[systemName]], argTypes=[Ljava.lang.Class;#5af349a6]
]. Message payload is of type: NullPayload
On a CompositeRoutingException, you can call:
exception.getExceptions().values()
to get an Array of Throwables thrown from within the scatter-gather. Then just re-throw the appropriate exception.
Using Groovy / Grails and log4j is there any way to ensure every exception thrown in the code is logged at error level.
Rather than having to find every catch block and explictly log it?
If not groovy / grails - a java suggestion will suffice.
Thanks
I don't believe there's any way to do this for handled exceptions, but you can do it for unhandled exceptions by adding the following to UrlMappings.groovy
"500"(controller: 'error')
Then create an ErrorController.groovy under grails-app/controllers
class ErrorController {
def index() {
Throwable exception = request?.exception?.cause
log.error 'something bad happened', exception
}
}