assume the code is correct and webservice timeout occurs.
The problem :
The system crashes and can not display the error message.
How to display error message? So I can provide an alternative to user when there is an error?
1)
I add this Class in the project :
public class MyClass
{
public static async Task LogInSuccess()
{
try
{
-- calling a web service here
}
catch (System.Exception _ex)
{
_strErrorMsg = _ex.InnerException.Message;
throw new Exception("LogInSuccess() " + _strErrorMsg);
}
}
}
--- In the MainPage,
2)
private async void SetUp ()
{
-- code for doing setUp task--
CallWebSvc();
}
3)
private void CallWebSvc()
{
bool ShowError = false;
System.Exception MyException = new Exception();
try
{
-- calling a web service thru the MyClass
System.Threading.Tasks.Task _blnLogInSuccess = MyClass.LogInSuccess();
await _blnLogInSuccess;
if (_blnLogInSuccess.IsCompleted)
{
g_blnLoginStatus = _blnLogInSuccess.Result;
}
}
catch (System.Exception _ex)
{
ShowError = true;
MyException = ex;
}
if (ShowError)
{
var MyMessageBox = new Windows.UI.Popups.MessageDialog("Remote Login Error:" + MyException.Message, "Start Login" );
await MyMessageBox.ShowAsync();
}
}
I assume your CallWebSvc method is async void (as, without async you cannot perform an await) If this is the case, you need to know async void doesn't do the same treatament to exceptions as async task. they aren't catched correctly. If you change your CallWebSvc from async void to async Task, you are going to receive the exception correctly.
Related
I'm facing an issue where I'm trying to write a more smart console app with logging and configuration available.
This is what I have so far:
namespace Client
{
public class Program
{
public static IConfigurationRoot Configuration;
private static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console(Serilog.Events.LogEventLevel.Debug)
.MinimumLevel.Debug()
.Enrich.FromLogContext()
.CreateLogger();
try
{
MainAsync(args).ConfigureAwait(false);
return 0;
}
catch
{
return 1;
}
}
private static async Task MainAsync(string[] args)
{
// Create service collection
Log.Information("Creating service collection");
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// Create service provider
Log.Information("Building service provider");
IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
try
{
Log.Information("Starting service");
await serviceProvider.GetService<App>().Run();
Log.Information("Ending service");
}
catch (Exception ex)
{
Log.Fatal(ex, "Error running service");
throw;
}
finally
{
Log.CloseAndFlush();
}
}
private static void ConfigureServices(IServiceCollection services)
{
// Add logging
services.AddSingleton(
LoggerFactory.Create(
builder => { builder.AddSerilog(dispose: true); }));
services.AddLogging();
// Build configuration
Configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
.AddJsonFile("appSettings.json", false)
.Build();
// Add access to generic IConfigurationRoot
services.AddSingleton(Configuration);
// Add app
services.AddTransient<App>();
}
}
}
I'm facing an issue in ConfigureServices method on line builder.AddSerilog for the life of me, I cannot figure out why it is not able to resolve AddSerilog
I was missing a package: Serilog.Extensions.Logging
For some reason, VS or even Resharper was not able to suggest this.
I have a vertx handler code where I do an executeBlocking but for it to work I need to put in a Thread.sleep() in order for the code in the blocking code to fully execute to the point that I can check the results.
Is there a better way around this so I don't do a Thread.sleep?
My handler code the following is the portion where I only kept the relevant components.
try (final VertxHttpResponse response = new VertxHttpResponse(context)) {
context.vertx().executeBlocking(
future -> {
...
try {
dispatcher.invokePropagateNotFound(request,
response);
future.complete();
} finally {
...
}
}, false,
res -> {
if (res.failed()) {
context.fail(wae);
} else {
if (!context.response().ended()) {
context.response().end();
}
}
});
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
}
My test and the relevant parts
#Test
public void test(final TestContext testContext) throws Exception {
final Router router = Router.router(rule.vertx());
final SpringJaxRsHandler handler = SpringJaxRsHandler.registerToRouter(router, MyApp.class);
final RoutingContext routingContext = mock(RoutingContext.class);
when(routingContext.currentRoute()).thenReturn(router.get("/api/hello"));
when(routingContext.vertx()).thenReturn(rule.vertx());
final HttpServerRequest serverRequest = mock(HttpServerRequest.class);
when(serverRequest.absoluteURI()).thenReturn("/api/hello");
when(serverRequest.isEnded()).thenReturn(true);
when(serverRequest.method()).thenReturn(HttpMethod.GET);
when(routingContext.request()).thenReturn(serverRequest);
final HttpServerResponse response = mock(HttpServerResponse.class);
when(response.putHeader(anyString(), anyString())).thenReturn(response);
when(response.headers()).thenReturn(new VertxHttpHeaders());
when(routingContext.response()).thenReturn(response);
handler.handle(routingContext);
Thread.sleep(1000);
// fails without the sleep above
verify(response, times(1)).setStatusCode(200);
}
I tried
testContext.assertTrue(routingContext.response().ended());
But that returned false.
I refactored the code a bit so I don't use routingContext directly but the concept is still the same. I use Async in combination of a when->then(Answer) and have the async.complete() be called in the Answer. Once that is done do an async.await() to wait for the thread to finish.
final Async async = testContext.async();
when(response.write(Matchers.any(Buffer.class))).then(invocation -> {
try {
return response;
} finally {
async.complete();
}
});
when(serverRequest.response()).thenReturn(response);
router.accept(serverRequest);
async.await();
I'm trying to unit test my exception filter code. I can validate the exception, but I can't seem to find the exception message to validate in the unit test. Here is my code...
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is TimeoutException)
{
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.RequestTimeout, context.Exception.Message);
return;
}
if (context.Exception is UnauthorizedAccessException)
{
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, context.Exception.Message);
return;
}
context.Response = context.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to process your request.");
}
}
Unit Test Code
[Theory, MemberData("ExceptionData")]
public void OnExceptionTests(Exception ex, HttpStatusCode statusCode)
{
var request = new HttpRequestMessage();
var actionContext = InitializeActionContext(request);
var httpActionExectuedContext = new HttpActionExecutedContext(actionContext, ex);
var exceptionHandlingAttribute = new ExceptionHandlingAttribute();
exceptionHandlingAttribute.OnException(httpActionExectuedContext);
Assert.Equal(actionContext.Response.StatusCode, statusCode);
Assert.Equal(actionContext.Response.ReasonPhrase, ex.Message);
}
public static IEnumerable<object[]> ExceptionData
{
get
{
return new[]
{
new object[] { new TimeoutException("My timeout message."), HttpStatusCode.RequestTimeout }
};
}
}
My problem is : Assert.Equal(actionContext.Response.ReasonPhrase, ex.Message);
When I try to look at it in the watch window, I can't seem to find "My Timeout message" in the response.
UPDATE:
actionContext.Response.ReasonPhrase = "Request Timeout"
ex.Message = "My timeout message"
The message portion of the CreateErrorResponse isn't a property, you have to read the content to get the value. Here's what I did...
var responseContent = await actionContext.Response.Content.ReadAsStringAsync();
After reading, responseContent now had:
{ "message" : "My timeout message." }
I am just starting with Akka and have created a test application. In it I create a bunch of actors who create a scheduler to generate a heartbeat event. Upon another type of event, I cancel the scheduler with heartbeat.cancel();, but I'd like to restart it when another event occurs. If I recreate the scheduler I see that the memory consumption increases continuously.
The question then would be either how do I resume the scheduler or how do I dispose the scheduler properly.
This is the code for that Actor
public class Device extends UntypedActor {
enum CommunicationStatus{
OK,
FAIL,
UNKNOWN
}
private static class Heartbeat {
}
public final String deviceId;
private CommunicationStatus commStatus;
private Cancellable heartBeatScheduler;
public Device(String Id)
{
deviceId = Id;
commStatus = CommunicationStatus.UNKNOWN;
}
#Override
public void preStart() {
getContext().system().eventStream().subscribe(getSelf(), DeviceCommunicationStatusUpdated.class);
startHeartbeat();
}
#Override
public void postStop() {
stopHeartBeat();
}
private void startHeartbeat() {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
log.info("Starting heartbeat");
heartBeatScheduler = getContext().system().scheduler().
schedule(Duration.Zero(),
Duration.create(1, TimeUnit.SECONDS),
getContext().self(),
new Heartbeat(),
getContext().system().dispatcher(),
ActorRef.noSender());
}
private void stopHeartBeat() {
if(!heartBeatScheduler.isCancelled()) {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
log.info("Stopping heartbeat");
heartBeatScheduler.cancel();
}
}
public String getDeviceId() {
return deviceId;
}
public CommunicationStatus getCommunicationStatus(){
return commStatus;
}
#Override
public void onReceive(Object message) throws Exception {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
if(message instanceof Heartbeat){
log.info("Pum, pum");
}
else if (message instanceof DeviceCommunicationStatusUpdated){
DeviceCommunicationStatusUpdated event = (DeviceCommunicationStatusUpdated) message;
if(event.deviceId == this.deviceId){
log.info("Received communication status update. '{}' is now {}", deviceId, event.state);
this.commStatus =
event.state == DeviceCommunicationStatusUpdated.State.OK ?
CommunicationStatus.OK : CommunicationStatus.FAIL;
if(commStatus == CommunicationStatus.OK && heartBeatScheduler.isCancelled()){
startHeartbeat();
}
else {
stopHeartBeat();
}
}
}
else unhandled(message);
}
}
Finally there is no leak, it's just that I'm new to Java and was impatient with the garbage collection. In any case, I would like to know about the resetting / restarting of a scheduler.
I keep getting a ConcurrencyException trying to update the same document multiple times in succession. PUT attempted on document '<id>' using a non current etag is the message.
On every save from our UI we publish an event using MassTransit. This event is sent to the subscriberqueues, but I put the Eventhandlers offline (testing offline subscribers). Once the eventhandler comes online the queue is read and the messages are processed as intended.
However since the same object is in the queue multiple times the first write succeeds, the next doesn't and throws this concurrencyexception.
I use a factory class to have a consistent IDocumentStore and IDocumentSession in all my applications. I specifically set the UseOptimisticConcurrency = false in the GetSession() method.
public static class RavenFactory
{
public static IDocumentStore CreateDocumentStore()
{
var store = new DocumentStore() { ConnectionStringName = "RavenDB" };
// Setting Conventions
store.Conventions.RegisterIdConvention<MyType>((db, cmd, e) => e.MyProperty.ToString());
store.Conventions.RegisterAsyncIdConvention<MyType>((db, cmd, e) => new CompletedTask<string>(e.MyProperty.ToString()));
// Registering Listeners
store
.RegisterListener(new TakeNewestConflictResolutionListener())
.RegisterListener(new DocumentConversionListener())
.RegisterListener(new DocumentStoreListener());
// Initialize and return
store.Initialize();
return store;
}
public static IDocumentSession GetSession(IDocumentStore store)
{
var session = store.OpenSession();
session.Advanced.UseOptimisticConcurrency = false;
return session;
}
}
The eventhandler looks like this. The IDocumentSession gets injected using Dependency Injection.
Here is the logic to get an instance of IDocumentSession.
private static void InitializeRavenDB(IUnityContainer container)
{
container.RegisterInstance<IDocumentStore>(RavenFactory.CreateDocumentStore(), new ContainerControlledLifetimeManager());
container.RegisterType<IDocumentSession, DocumentSession>(new PerResolveLifetimeManager(), new InjectionFactory(c => RavenFactory.GetSession(c.Resolve<IDocumentStore>())));
}
And here is the actual EventHandler which has the ConcurrencyException.
public class MyEventHandler:Consumes<MyEvent>.All, IConsumer
{
private readonly IDocumentSession _session;
public MyEventHandler(IDocumentSession session)
{
if (session == null) throw new ArgumentNullException("session");
_session = session;
}
public void Consume(MyEvent message)
{
Console.WriteLine("MyEvent received: Id = '{0}'", message.MyProperty);
try
{
_session.Store(message);
_session.SaveChanges();
}
catch (Exception ex)
{
var exc = ex.ToString();
// Deal with concurrent writes ...
throw;
}
}
}
I want to ignore any concurrencyexception for now until we can sort out with the business on how to tackle concurrency.
So, any ideas why I get the ConcurrencyException? I want the save to happen no matter whether the document has been updated before or not.
I am unfamiliar with configuring Unity, but you always want Singleton of the IDocumentStore. Below, I have coded the Singleton out manually, but I'm sure Unity would support it:
public static class RavenFactory
{
private static IDocumentStore store;
private static object syncLock = new object();
public static IDocumentStore CreateDocumentStore()
{
if(RavenFactory.store != null)
return RavenFactory.store;
lock(syncLock)
{
if(RavenFactory.store != null)
return RavenFactory.store;
var localStore = new DocumentStore() { ConnectionStringName = "RavenDB" };
// Setting Conventions
localStore .Conventions.RegisterIdConvention<MyType>((db, cmd, e) => e.MyProperty.ToString());
localStore .Conventions.RegisterAsyncIdConvention<MyType>((db, cmd, e) => new CompletedTask<string>(e.MyProperty.ToString()));
// Registering Listeners
localStore
.RegisterListener(new TakeNewestConflictResolutionListener())
.RegisterListener(new DocumentConversionListener())
.RegisterListener(new DocumentStoreListener());
// Initialize and return
localStore.Initialize();
RavenFactory.store = localStore;
return RavenFactory.store;
}
}
// As before
// public static IDocumentSession GetSession(IDocumentStore store)
//
}