loading...

CoreLMS: Logging, Custom Exceptions, and more TDD

fitzycodesthings profile image John "Fitzy" DeLancey Originally published at fct.dev ・2 min read

This week was a GREAT learning week for me. Got a lot more comfortable with the TDD mindset and got some good, solid infrastructure in place.

Project feels like it's moving rather slowly for the moment (especially since I'm only working on it one day a week), but the pace will pick up quickly, especially as I continue getting comfortable with "the flow."

Get the Git

GitHub logo FitzyCodesThings / core-lms

An open source online learning management system project in ASP.Net Core MVC. Explores many best practices and patterns in modern software development.

Watch the Replay

Skip to the Good Stuff

  • Configuring logging 5:43
  • Adding a custom exception 24:51
  • TDD/Next Services 30:47

Project Update

Made solid progress if not a LOT of it. I'm still getting my feet wet on implementing the TDD flow (and the unit tests themselves).

Did have a great realization while working on this though.

It was when I got to this state of the new GetCourseAsync business logic method (which is covered by tests for context).

public async Task<Course> GetCourseAsync(int id)
{
    var course = await this.db.SelectCourseByIdAsync(id);

    if (course == null)
    {
        logger.LogWarning($"Course {id} not found.");
        throw new ApplicationException($"Course {id} not found.");
    }

    return course;
}

Can you spot the problem?

It's not actually a problem, really, so much as it is a misapplication of ideas.

I discovered the issue when I was trying to figure out how to log the actual exception that was (about to be) thrown. Obviously I can't do that, so what do I do?

The light bulb began to go off when my good friend TheGrumpyGameDev in chat confirmed it for me:

I shouldn't need to log anything (or at least exception conditions) inside of business logic that's under unit testing.

(Not saying this is true 100% of the time, but it certainly applies in this case.)

The logging in this instance should occur (IF REQUIRED) in whatever calling code catches the exception.

In some situations, the exception may be perfectly acceptable, so why would I log a warning about that?

I realize this (as so many things I write/do) seems very basic, but like I said: this project is about filling in gaps in my knowledge, and some of those are, well, pretty basic.

In any case, the method code got simplified down to this well-covered simpler bit:

public async Task<Course> GetCourseAsync(int id)
{
    var course = await this.db.SelectCourseByIdAsync(id);

    if (course == null)               
        throw new ApplicationException($"Course {id} not found.");                

    return course;
}

Easy-peasy.

Wrapping Up

Looking forward to the pace picking up and getting through the basic infrastructure. I wanna see this thing in action! Probably won't be next week, but we'll get there soon.

Until next time!

- John

Posted on by:

fitzycodesthings profile

John "Fitzy" DeLancey

@fitzycodesthings

I'm a (primarily) DotNet developer and software consultant with 15+ years of experience. Lovin' live coding on Twitch.

Discussion

markdown guide