Преглед изворни кода

Add exception handler middleware to format exceptions as JSON.
Add custom exception for MAX error responses.

Andrew Klopper пре 8 година
родитељ
комит
46fa845bf0

+ 10 - 74
BulkPrintingAPI/Controllers/LoginController.cs

@@ -61,48 +61,11 @@ namespace BulkPrintingAPI.Controllers
61 61
             if (!ModelState.IsValid)
62 62
                 return BadRequest();
63 63
 
64
-            MAX.Models.User user;
65
-            try
66
-            {
67
-                user = await MAX.Utils.AuthenticateUserAsync(_clientFactory, _logger,
68
-                    loginRequest.UserId.Value, loginRequest.Username, loginRequest.VendorId.Value,
69
-                    loginRequest.SerialNumber, loginRequest.Password);
70
-            }
71
-            catch (Exception e)
72
-            {
73
-                _logger.LogError(
74
-                    "AuthenticateUserAsync failed for {0}: {1}",
75
-                    MAX.LoginCredentials.Format(loginRequest.UserId.Value, loginRequest.Username,
76
-                        loginRequest.VendorId.Value, loginRequest.SerialNumber),
77
-                    e.Message);
78
-                return Unauthorized();
79
-            }
80
-
81
-            if (user == null)
82
-            {
83
-                _logger.LogInformation(
84
-                    "Login failed for {0}",
85
-                    MAX.LoginCredentials.Format(loginRequest.UserId.Value, loginRequest.Username,
86
-                        loginRequest.VendorId.Value, loginRequest.SerialNumber));
87
-                return Unauthorized();
88
-            }
89
-
90
-            MAX.LoginCredentials credentials;
91
-            try
92
-            {
93
-                credentials = await Utils.SyncUserAndVendorWithDbAsync(_context, _dataEncryptionOptions,
94
-                    user, loginRequest.Password, loginRequest.VendorId.Value, loginRequest.SerialNumber);
95
-            }
96
-            catch (Exception e)
97
-            {
98
-                _logger.LogError(
99
-                    "SyncUserAndVendorWithDb failed for {0}: {1}",
100
-                    MAX.LoginCredentials.Format(loginRequest.UserId.Value, loginRequest.Username,
101
-                        loginRequest.VendorId.Value, loginRequest.SerialNumber),
102
-                    e.Message);
103
-                return Unauthorized();
104
-            }
105
-
64
+            var user = await MAX.Utils.AuthenticateUserAsync(_clientFactory, _logger,
65
+                loginRequest.UserId.Value, loginRequest.Username, loginRequest.VendorId.Value,
66
+                loginRequest.SerialNumber, loginRequest.Password);
67
+            var credentials = await Utils.SyncUserAndVendorWithDbAsync(_context, _dataEncryptionOptions,
68
+                user, loginRequest.Password, loginRequest.VendorId.Value, loginRequest.SerialNumber);
106 69
             var now = DateTimeOffset.UtcNow;
107 70
 
108 71
             _context.VendorEvents.Add(new MAX.Models.VendorEvent()
@@ -170,38 +133,11 @@ namespace BulkPrintingAPI.Controllers
170 133
         public async Task<IActionResult> ExtendTokenAsync()
171 134
         {
172 135
             var credentials = await Utils.GetLoginCredentialsFromRequestAsync(HttpContext, _context);
173
-
174
-            MAX.Models.User user;
175
-            try
176
-            {
177
-                user = await MAX.Utils.AuthenticateUserAsync(_clientFactory, _logger,
178
-                    credentials.User.Id, credentials.User.Username, credentials.Vendor.Id,
179
-                    credentials.Vendor.SerialNumber, credentials.Password);
180
-            }
181
-            catch (Exception e)
182
-            {
183
-                _logger.LogError(
184
-                    "AuthenticateUserAsync failed for {0}: {1}",
185
-                    MAX.LoginCredentials.Format(credentials.User.Id, credentials.User.Username, credentials.Vendor.Id,
186
-                        credentials.Vendor.SerialNumber), e.Message);
187
-                return Unauthorized();
188
-            }
189
-
190
-            MAX.LoginCredentials possiblyUpdatedCredentials;
191
-            try
192
-            {
193
-                possiblyUpdatedCredentials = await Utils.SyncUserAndVendorWithDbAsync(_context, _dataEncryptionOptions,
194
-                    user, credentials.Password, credentials.Vendor.Id, credentials.Vendor.SerialNumber);
195
-            }
196
-            catch (Exception e)
197
-            {
198
-                _logger.LogError(
199
-                    "SyncUserAndVendorWithDb failed for {0}: {1}",
200
-                    MAX.LoginCredentials.Format(credentials.User.Id, credentials.User.Username, credentials.Vendor.Id,
201
-                        credentials.Vendor.SerialNumber), e.Message);
202
-                return Unauthorized();
203
-            }
204
-
136
+            var user = await MAX.Utils.AuthenticateUserAsync(_clientFactory, _logger,
137
+                credentials.User.Id, credentials.User.Username, credentials.Vendor.Id,
138
+                credentials.Vendor.SerialNumber, credentials.Password);
139
+            var possiblyUpdatedCredentials = await Utils.SyncUserAndVendorWithDbAsync(_context, _dataEncryptionOptions,
140
+                user, credentials.Password, credentials.Vendor.Id, credentials.Vendor.SerialNumber);
205 141
             var now = DateTimeOffset.UtcNow;
206 142
 
207 143
             _context.VendorEvents.Add(new MAX.Models.VendorEvent()

+ 73 - 0
BulkPrintingAPI/Middleware/ExceptionHandlerMiddleware.cs

@@ -0,0 +1,73 @@
1
+using MAX;
2
+using Microsoft.AspNetCore.Http;
3
+using Microsoft.Extensions.Logging;
4
+using Newtonsoft.Json;
5
+using System;
6
+using System.Threading.Tasks;
7
+
8
+namespace BulkPrintingAPI.Middleware
9
+{
10
+    public class ExceptionHandlerMiddleware
11
+    {
12
+        private readonly RequestDelegate _next;
13
+        private ILogger _logger;
14
+
15
+        private class ErrorResponse
16
+        {
17
+            public ErrorResponse(string message)
18
+            {
19
+                code = null;
20
+                error = message;
21
+            }
22
+
23
+            public ErrorResponse(MAXException e)
24
+            {
25
+                code = e.ErrorCode;
26
+                error = e.Message;
27
+            }
28
+
29
+            public int? code { get; set; }
30
+
31
+            public string error { get; set; }
32
+        }
33
+
34
+        public ExceptionHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
35
+        {
36
+            _next = next;
37
+            _logger = loggerFactory.CreateLogger(GetType().FullName);
38
+        }
39
+
40
+        public async Task Invoke(HttpContext context)
41
+        {
42
+            try
43
+            {
44
+                await _next(context);
45
+            }
46
+            catch (Exception e)
47
+            {
48
+                if (context.Response.HasStarted)
49
+                {
50
+                    _logger.LogWarning("Response has already started; exception will be rethrown");
51
+                    throw;
52
+                }
53
+
54
+                _logger.LogError(0, e, "Unhandled exception");
55
+
56
+                ErrorResponse response;
57
+                if (e is MAXException)
58
+                {
59
+                    response = new ErrorResponse((MAXException)e);
60
+                }
61
+                else
62
+                {
63
+                    // Don't want to leak arbitrary exception messages to the user
64
+                    response = new ErrorResponse("The server encountered an unexpected error");
65
+                }
66
+
67
+                context.Response.StatusCode = 500;
68
+                context.Response.ContentType = "application/json";
69
+                await context.Response.WriteAsync(JsonConvert.SerializeObject(response));
70
+            }
71
+        }
72
+    }
73
+}

+ 3 - 0
BulkPrintingAPI/Startup.cs

@@ -1,4 +1,5 @@
1 1
 using BulkPrintingAPI.Configuration;
2
+using BulkPrintingAPI.Middleware;
2 3
 using Microsoft.AspNetCore.Authorization;
3 4
 using Microsoft.AspNetCore.Builder;
4 5
 using Microsoft.AspNetCore.Hosting;
@@ -80,6 +81,8 @@ namespace BulkPrintingAPI
80 81
                 TokenValidationParameters = tokenValidationParameters
81 82
             };
82 83
 
84
+            app.UseMiddleware<ExceptionHandlerMiddleware>();
85
+
83 86
             app.UseJwtBearerAuthentication(bearerOptions);
84 87
 
85 88
             app.UseMvc();

+ 123 - 144
MAXClient/Client.cs

@@ -86,12 +86,7 @@ namespace MAX
86 86
                 .Append(_vendorId)
87 87
                 .Append("|123451234512345||||||")).ConfigureAwait(false);
88 88
 
89
-            var response = await ReadMessageAsync().ConfigureAwait(false);
90
-            if (!response.StartsWith("Hi "))
91
-            {
92
-                _logger.LogError("Device authentication failed: {0}", response);
93
-                return null;
94
-            }
89
+            var response = ExpectResponse(await ReadMessageAsync().ConfigureAwait(false), "Hi");
95 90
 
96 91
             // Request server RSA key
97 92
             await WriteMessageAsync(new MessageBuilder().Append("PK")).ConfigureAwait(false);
@@ -104,11 +99,7 @@ namespace MAX
104 99
                 .Append("3D ")
105 100
                 .Append(EncryptRSA(response, BitConverter.ToString(_des.Key).Replace("-", "")))).ConfigureAwait(false);
106 101
 
107
-            response = await ReadMessageAsync().ConfigureAwait(false);
108
-            if (!response.StartsWith("OK"))
109
-            {
110
-                throw new Exception(String.Format("Key exchange failed: {0}", response));
111
-            }
102
+            response = ExpectResponse(await ReadMessageAsync().ConfigureAwait(false), "OK");
112 103
 
113 104
             // User authentication
114 105
             await WriteMessageAsync(new MessageBuilder()
@@ -120,51 +111,40 @@ namespace MAX
120 111
                     .Append("|")
121 112
                     .Append(_password).ToString()))).ConfigureAwait(false);
122 113
 
123
-            response = Decrypt(await ReadMessageAsync().ConfigureAwait(false));
124
-            if (response.StartsWith("OK"))
125
-            {
126
-                var parts = response.Split('|');
127
-                var user = new User()
128
-                {
129
-                    Id = _userId,
130
-                    Username = _username,
131
-                    FirstName = parts[4],
132
-                    Surname = parts[3],
133
-                    Enabled = bool.Parse(parts[6]),
134
-                    Level = (User.UserLevel)int.Parse(parts[1]),
135
-                    System = int.Parse(parts[2]),
136
-                    LastLogin = DateTime.Parse(parts[5])
137
-                };
138
-
139
-                if (user.Level == User.UserLevel.CustomUser)
140
-                {
141
-                    user.CanPrintOffline = bool.Parse(parts[7]);
142
-                    user.OfflinePrintValue = decimal.Parse(parts[8]);
143
-                    user.CanPrintOnline = bool.Parse(parts[9]);
144
-                    user.OnlinePrintValue = decimal.Parse(parts[10]);
145
-                    user.CanReprintOffline = bool.Parse(parts[11]);
146
-                    user.OfflineReprintValue = decimal.Parse(parts[12]);
147
-                    user.CanReprintOnline = bool.Parse(parts[13]);
148
-                    user.OnlineReprintValue = decimal.Parse(parts[14]);
149
-                    user.BulkExport = bool.Parse(parts[15]);
150
-                    user.BulkExportMaxValue = decimal.Parse(parts[16]);
151
-                    user.BulkOrder = bool.Parse(parts[17]);
152
-                    user.BulkOrderMaxValue = decimal.Parse(parts[18]);
153
-                    user.BulkViewPins = bool.Parse(parts[19]);
154
-                    user.BulkReExport = bool.Parse(parts[20]);
155
-                }
114
+            response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
156 115
 
157
-                return user;
158
-            }
159
-            else if (response.StartsWith("ER"))
116
+            var parts = response.Split('|');
117
+            var user = new User()
160 118
             {
161
-                _logger.LogInformation("User authentication failed: {0}", response);
162
-                return null;
163
-            }
164
-            else
119
+                Id = _userId,
120
+                Username = _username,
121
+                FirstName = parts[4],
122
+                Surname = parts[3],
123
+                Enabled = bool.Parse(parts[6]),
124
+                Level = (User.UserLevel)int.Parse(parts[1]),
125
+                System = int.Parse(parts[2]),
126
+                LastLogin = DateTime.Parse(parts[5])
127
+            };
128
+
129
+            if (user.Level == User.UserLevel.CustomUser)
165 130
             {
166
-                throw new Exception(String.Format("Invalid user information response: {0}", response));
131
+                user.CanPrintOffline = bool.Parse(parts[7]);
132
+                user.OfflinePrintValue = decimal.Parse(parts[8]);
133
+                user.CanPrintOnline = bool.Parse(parts[9]);
134
+                user.OnlinePrintValue = decimal.Parse(parts[10]);
135
+                user.CanReprintOffline = bool.Parse(parts[11]);
136
+                user.OfflineReprintValue = decimal.Parse(parts[12]);
137
+                user.CanReprintOnline = bool.Parse(parts[13]);
138
+                user.OnlineReprintValue = decimal.Parse(parts[14]);
139
+                user.BulkExport = bool.Parse(parts[15]);
140
+                user.BulkExportMaxValue = decimal.Parse(parts[16]);
141
+                user.BulkOrder = bool.Parse(parts[17]);
142
+                user.BulkOrderMaxValue = decimal.Parse(parts[18]);
143
+                user.BulkViewPins = bool.Parse(parts[19]);
144
+                user.BulkReExport = bool.Parse(parts[20]);
167 145
             }
146
+
147
+            return user;
168 148
         }
169 149
 
170 150
         public int ConnectTimeout { get; set; }
@@ -262,28 +242,21 @@ namespace MAX
262 242
         public async Task<Account> GetAccountAsync()
263 243
         {
264 244
             await WriteMessageAsync(new MessageBuilder().Append("Acc")).ConfigureAwait(false);
265
-            var response = Decrypt(await ReadMessageAsync().ConfigureAwait(false));
266
-            if (response.StartsWith("OK"))
245
+            var response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
246
+            var parts = response.Split('|');
247
+            return new Account()
267 248
             {
268
-                var parts = response.Split('|');
269
-                return new Account()
249
+                Id = int.Parse(parts[1]),
250
+                Name = parts[2],
251
+                Balance = decimal.Parse(parts[3]),
252
+                Status = (Account.AccountStatus)int.Parse(parts[4]),
253
+                Reference = parts[5],
254
+                Warehouse = new Warehouse()
270 255
                 {
271
-                    Id = int.Parse(parts[1]),
272
-                    Name = parts[2],
273
-                    Balance = decimal.Parse(parts[3]),
274
-                    Status = (Account.AccountStatus)int.Parse(parts[4]),
275
-                    Reference = parts[5],
276
-                    Warehouse = new Warehouse()
277
-                    {
278
-                        Id = int.Parse(parts[6]),
279
-                        Name = parts[7]
280
-                    }
281
-                };
282
-            }
283
-            else
284
-            {
285
-                throw new Exception(String.Format("Invalid account information response: {0}", response));
286
-            }
256
+                    Id = int.Parse(parts[6]),
257
+                    Name = parts[7]
258
+                }
259
+            };
287 260
         }
288 261
 
289 262
         public async Task<ProductCatalogue> GetProductCatalogueAsync(Account account)
@@ -292,51 +265,39 @@ namespace MAX
292 265
             await WriteMessageAsync(new MessageBuilder()
293 266
                 .Append("Pdt ")
294 267
                 .Append(encryptedWarehouseName)).ConfigureAwait(false);
295
-            var response = Decrypt(await ReadMessageAsync().ConfigureAwait(false));
296
-            if (response.StartsWith("OK"))
297
-            {
298
-                var parts = response.Split('|');
299
-                var count = int.Parse(parts[1]);
268
+            var response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
300 269
 
301
-                var catalogue = new ProductCatalogue();
270
+            var parts = response.Split('|');
271
+            var count = int.Parse(parts[1]);
272
+
273
+            var catalogue = new ProductCatalogue();
302 274
             
303
-                var listCommand = new MessageBuilder().Append("List ")
304
-                    .Append(encryptedWarehouseName).GetBytes();
305
-                for (var i = 0; i < count; i++)
275
+            var listCommand = new MessageBuilder().Append("List ")
276
+                .Append(encryptedWarehouseName).GetBytes();
277
+            for (var i = 0; i < count; i++)
278
+            {
279
+                await _connectionStream.WriteAsync(listCommand, 0, listCommand.Length).ConfigureAwait(false);
280
+                response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
281
+
282
+                parts = response.Split('|');
283
+                int networkId = int.Parse(parts[4]);
284
+                Network network;
285
+                if (! catalogue.NetworkMap.TryGetValue(networkId, out network))
306 286
                 {
307
-                    await _connectionStream.WriteAsync(listCommand, 0, listCommand.Length).ConfigureAwait(false);
308
-                    response = Decrypt(await ReadMessageAsync().ConfigureAwait(false));
309
-                    if (response.StartsWith("OK"))
310
-                    {
311
-                        parts = response.Split('|');
312
-                        int networkId = int.Parse(parts[4]);
313
-                        Network network;
314
-                        if (! catalogue.NetworkMap.TryGetValue(networkId, out network))
315
-                        {
316
-                            network = catalogue.AddNetwork(networkId, parts[5]);
317
-                        }
318
-
319
-                        catalogue.AddProduct(
320
-                            network: network,
321
-                            id: int.Parse(parts[1]),
322
-                            faceValue: decimal.Parse(parts[2]),
323
-                            description: parts[3],
324
-                            voucherType: (Batch.Vouchertype)int.Parse(parts[6]),
325
-                            discountPercentage: decimal.Parse(parts[7])
326
-                        );
327
-                    }
328
-                    else
329
-                    {
330
-                        throw new Exception(String.Format("Invalid product item response: {0}", response));
331
-                    }
287
+                    network = catalogue.AddNetwork(networkId, parts[5]);
332 288
                 }
333 289
 
334
-                return catalogue;
335
-            }
336
-            else
337
-            {
338
-                throw new Exception(String.Format("Invalid product catalogue response: {0}", response));
290
+                catalogue.AddProduct(
291
+                    network: network,
292
+                    id: int.Parse(parts[1]),
293
+                    faceValue: decimal.Parse(parts[2]),
294
+                    description: parts[3],
295
+                    voucherType: (Batch.Vouchertype)int.Parse(parts[6]),
296
+                    discountPercentage: decimal.Parse(parts[7])
297
+                );
339 298
             }
299
+
300
+            return catalogue;
340 301
         }
341 302
 
342 303
         public async Task<OrderResponse> PlaceOrderAsync(int accountId, Product product, int quantity,
@@ -365,42 +326,35 @@ namespace MAX
365 326
                     .Append(internalReference)
366 327
                     .ToString()))).ConfigureAwait(false);
367 328
 
368
-            var response = Decrypt(await ReadMessageAsync().ConfigureAwait(false));
329
+            var response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
369 330
 
370
-            if (response.StartsWith("OK"))
331
+            var parts = response.Split('|');
332
+            return new OrderResponse()
371 333
             {
372
-                var parts = response.Split('|');
373
-                return new OrderResponse()
334
+                Batch = new Batch()
374 335
                 {
375
-                    Batch = new Batch()
376
-                    {
377
-                        Id = int.Parse(parts[1]),
378
-                        OrderReference = parts[2],
379
-                        RequestedQuantity = int.Parse(parts[3]),
380
-                        DeliveredQuantity = int.Parse(parts[4]),
381
-                        Cost = decimal.Parse(parts[5]),
382
-                        InternalReference = internalReference,
383
-                        OrderGuid = orderGuid,
384
-                        AccountId = accountId,
385
-                        VendorId = _vendorId,
386
-                        ProductId = product.Id,
387
-                        ProductDescription = product.Description,
388
-                        VoucherType = product.VoucherType,
389
-                        FaceValue = product.FaceValue,
390
-                        DiscountPercentage = product.DiscountPercentage,
391
-                        NetworkId = product.Network.Id,
392
-                        NetworkName = product.Network.Name,
393
-                        OrderDate = DateTimeOffset.UtcNow,
394
-                        OrderedById = _userId,
395
-                        ReadyForDownload = false
396
-                    },
397
-                    RemainingBalance = decimal.Parse(parts[6])
398
-                };
399
-            }
400
-            else
401
-            {
402
-                throw new Exception(string.Format("Invalid order response: {0}", response));
403
-            }
336
+                    Id = int.Parse(parts[1]),
337
+                    OrderReference = parts[2],
338
+                    RequestedQuantity = int.Parse(parts[3]),
339
+                    DeliveredQuantity = int.Parse(parts[4]),
340
+                    Cost = decimal.Parse(parts[5]),
341
+                    InternalReference = internalReference,
342
+                    OrderGuid = orderGuid,
343
+                    AccountId = accountId,
344
+                    VendorId = _vendorId,
345
+                    ProductId = product.Id,
346
+                    ProductDescription = product.Description,
347
+                    VoucherType = product.VoucherType,
348
+                    FaceValue = product.FaceValue,
349
+                    DiscountPercentage = product.DiscountPercentage,
350
+                    NetworkId = product.Network.Id,
351
+                    NetworkName = product.Network.Name,
352
+                    OrderDate = DateTimeOffset.UtcNow,
353
+                    OrderedById = _userId,
354
+                    ReadyForDownload = false
355
+                },
356
+                RemainingBalance = decimal.Parse(parts[6])
357
+            };
404 358
         }
405 359
 
406 360
         private async Task<byte[]> ReadBytesAsync(int count)
@@ -432,6 +386,31 @@ namespace MAX
432 386
 
433 387
         public int SendTimeout { get; set; }
434 388
 
389
+        private string ExpectResponse(string response, string prefix)
390
+        {
391
+            if (response.StartsWith("ER"))
392
+            {
393
+                var parts = response.Split('|');
394
+                int errorCode;
395
+                if ((parts.Length < 2) || ! int.TryParse(parts[1], out errorCode))
396
+                {
397
+                    errorCode = -1;
398
+                }
399
+                var message = parts.Length >= 3 ? parts[2] : String.Format("Malformed server error: {0}", response);
400
+                _logger.LogError("MAX Error for {0}: {1} (code {2})",
401
+                    LoginCredentials.Format(_userId, _username, _vendorId, _serialNumber), message, errorCode);
402
+                throw new MAXException(errorCode, message);
403
+            }
404
+            else if (! response.StartsWith(prefix))
405
+            {
406
+                _logger.LogError("Invalid MAX response for {0}: {1}",
407
+                    LoginCredentials.Format(_userId, _username, _vendorId, _serialNumber),
408
+                    response);
409
+                throw new Exception(String.Format("Invalid server response: {0}", response));
410
+            }
411
+            return response;
412
+        }
413
+
435 414
         private async Task WriteMessageAsync(MessageBuilder message)
436 415
         {
437 416
             byte[] data = message.GetBytes();

+ 29 - 0
MAXClient/MAXException.cs

@@ -0,0 +1,29 @@
1
+using System;
2
+
3
+namespace MAX
4
+{
5
+    public class MAXException : Exception
6
+    {
7
+        private int _errorCode;
8
+
9
+        public MAXException() { }
10
+
11
+        public MAXException(int errorCode, string message)
12
+            : base(message)
13
+        {
14
+            _errorCode = errorCode;
15
+        }
16
+
17
+        public MAXException(int errorCode, string message, Exception innerException)
18
+            : base(message, innerException)
19
+        {
20
+            _errorCode = errorCode;
21
+        }
22
+
23
+        public int ErrorCode
24
+        {
25
+            get { return _errorCode; }
26
+            set { _errorCode = value; }
27
+        }
28
+    }
29
+}

+ 3 - 16
MAXClient/Utils.cs

@@ -65,10 +65,7 @@ namespace MAX
65 65
                 userId, username, password))
66 66
             {
67 67
                 var user = await client.ConnectAsync().ConfigureAwait(false);
68
-                if (user != null)
69
-                {
70
-                    user.Account = await client.GetAccountAsync().ConfigureAwait(false);
71
-                }
68
+                user.Account = await client.GetAccountAsync().ConfigureAwait(false);
72 69
                 return user;
73 70
             }
74 71
         }
@@ -78,12 +75,7 @@ namespace MAX
78 75
         {
79 76
             using (var client = clientFactory.GetClient(logger, credentials))
80 77
             {
81
-                var user = await client.ConnectAsync().ConfigureAwait(false);
82
-                if (user == null)
83
-                {
84
-                    throw new Exception(string.Format("Invalid login credentials for {0}",
85
-                        credentials.ToString()));
86
-                }
78
+                await client.ConnectAsync().ConfigureAwait(false);
87 79
                 return await client.GetProductCatalogueAsync(credentials.User.Account).ConfigureAwait(false);
88 80
             }
89 81
         }
@@ -95,12 +87,7 @@ namespace MAX
95 87
         {
96 88
             using (var client = clientFactory.GetClient(logger, credentials))
97 89
             {
98
-                var user = await client.ConnectAsync().ConfigureAwait(false);
99
-                if (user == null)
100
-                {
101
-                    throw new Exception(string.Format("Invalid login credentials for {0}",
102
-                        credentials.ToString()));
103
-                }
90
+                await client.ConnectAsync().ConfigureAwait(false);
104 91
                 return await client.PlaceOrderAsync(credentials.User.AccountId,
105 92
                     product, quantity, customerReference, internalReference, orderGuid, key).ConfigureAwait(false);
106 93
             }