C# Professional - Basics & OOP - Exercises
talent-agile
39.9K views
Exception Handling - Mini-Project
This mini project will help you understand how to handle exceptions from real code.
Logging exceptions
The basic need is the simple one.
Change the code to make sure that all exceptions are logged, then rethrown to the calling code.
Catching a generic exception
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// {
using System;
using System.Linq;
namespace Exceptions
{
public class UserReport
{
private readonly IUserRepository _userRepository;
private readonly IFileSystem _fileSystem;
public UserReport(ILog logger, IUserRepository userRepository, IFileSystem fileSystem)
{
_logger = logger;
_userRepository = userRepository;
_fileSystem = fileSystem;
}
// }
private readonly ILog _logger;
public bool SaveListOfUsers(string filePath)
{
var allUsers = _userRepository.GetAllUsers();
var exportData = string.Join(Environment.NewLine, allUsers.Select(user => $"{user.FirstName} {user.LastName}"));
if (_fileSystem.FileExists(filePath))
{
_fileSystem.Delete(filePath);
}
_fileSystem.WriteAllLines(filePath, exportData);
return true;
}
// {
}
}
// }
1
using System;
Handling file I/O exceptions
As the code is writing to a file for the export, it may fail if the user running the code has insufficient rights.
We need to handle this case by adding two rules:
- Catch exceptions of type
UnauthorizedAccessException
- Log these exceptions
- Make sure the method will not throw an exception, but should return
false
to indicate that the export was not done
Handling exceptions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// {
using System;
using System.Linq;
namespace Exceptions
{
public class UserReport
{
private readonly IUserRepository _userRepository;
private readonly IFileSystem _fileSystem;
public UserReport(ILog logger, IUserRepository userRepository, IFileSystem fileSystem)
{
_logger = logger;
_userRepository = userRepository;
_fileSystem = fileSystem;
}
// }
private readonly ILog _logger;
public bool SaveListOfUsers(string filePath)
{
var allUsers = _userRepository.GetAllUsers();
var exportData = string.Join(Environment.NewLine, allUsers.Select(user => $"{user.FirstName} {user.LastName}"));
if (_fileSystem.FileExists(filePath))
{
_fileSystem.Delete(filePath);
}
_fileSystem.WriteAllLines(filePath, exportData);
return true;
}
// {
}
}
// }
1
using System;
Wrap other exceptions
If a NullReferenceException
is raised, mainly for technical issues, we will catch it and wrap it in an InvalidOperationException
with a proper exception message indicating that the export was not done.
Implement these new rules:
- Catch exceptions of type
NullReferenceException
- Log the exception
- Make the method throw a new exception of type
InvalidOperationException
- The new exception must have a message "Could not create the report, check logs for more details"
- The new exception must have a reference to the caught one
Wrapping in a new exception
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// {
using System;
using System.Linq;
namespace Exceptions
{
public class UserReport
{
private readonly IUserRepository _userRepository;
private readonly IFileSystem _fileSystem;
public UserReport(ILog logger, IUserRepository userRepository, IFileSystem fileSystem)
{
_logger = logger;
_userRepository = userRepository;
_fileSystem = fileSystem;
}
// }
private readonly ILog _logger;
public bool SaveListOfUsers(string filePath)
{
var allUsers = _userRepository.GetAllUsers();
var exportData = string.Join(Environment.NewLine, allUsers.Select(user => $"{user.FirstName} {user.LastName}"));
if (_fileSystem.FileExists(filePath))
{
_fileSystem.Delete(filePath);
}
_fileSystem.WriteAllLines(filePath, exportData);
return true;
}
// {
}
}
// }
1
using System;
All combined
Before pushing our code to production, make sure that all three cases are handled correctly at the same time.
Wrapping in a new exception
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// {
using System;
using System.Linq;
namespace Exceptions
{
public class UserReport
{
private readonly IUserRepository _userRepository;
private readonly IFileSystem _fileSystem;
public UserReport(ILog logger, IUserRepository userRepository, IFileSystem fileSystem)
{
_logger = logger;
_userRepository = userRepository;
_fileSystem = fileSystem;
}
// }
private readonly ILog _logger;
public bool SaveListOfUsers(string filePath)
{
var allUsers = _userRepository.GetAllUsers();
var exportData = string.Join(Environment.NewLine, allUsers.Select(user => $"{user.FirstName} {user.LastName}"));
if (_fileSystem.FileExists(filePath))
{
_fileSystem.Delete(filePath);
}
_fileSystem.WriteAllLines(filePath, exportData);
return true;
}
// {
}
}
// }
1
using System;
Create your playground on Tech.io
This playground was created on Tech.io, our hands-on, knowledge-sharing platform for developers.