Mud vs Sheep vs Bike, the song

Mud vs Sheep vs Bike (MvSvB) is an event that my friend Fraser and I started in about 1993. I’ve written about it on here before. Essentially it’s just a bunch of friends going mountain biking in Wales, but it has achieved a kind of independent existence in our collective consciousness. It’s loosely named after the famous “Man vs Horse vs Bike” race that I regretted once entering in about 1991. MvSvB has been held at various youth hostels and other group rental accommodations, but most often at what was my Dad’s farm near Llandovery in Wales.

Certain MvSvB traditions have been established, most importantly:

  • Banoffee pie
  • T-shirts
  • Getting wet and muddy
  • Getting lost
  • Punctures and disintegrating wheels
  • Being chased by fierce sheepdogs
  • Beer

Banoffee pie is a critical component of the coping mechanisms required to spend much time in Welsh weather, and is a great source of the calories required for biking up hills (at least that’s our excuse). Some terms for the unaware: liquid sun = rain, Welsh not raining = light drizzle.

I’ve designed most of the T-shirts to date, starting in 1995, when I learned that half-toning really isn’t a good approach for screen printing on fabrics. The designs usually tried to have 1 or 2-colour prints using strong mountain bike themes with in-jokes, references to mud, sheep, bikes, hills, etc. This year I came up with a bold design, based on a picture of a friend on a bike, carefully redrawn with an Apple Pencil on my iPad (using Linearity Curve), and printed using a groovy high-tech direct-to-fabric printing process by my friends at Vektor.

Since I moved to France in 2009, I’ve missed out on a few events, Fraser moved to New Zealand, we’ve mostly had growing kids to contend with, the whole age thing, and so MvSvB events have dwindled. But 2023 is the comeback year, the kids are big enough to leave at home, and we can reunite to enjoy a collective mid-life crisis.

To commemorate what we are officially calling the 30th anniversary of MvSvB, I wrote this song about it, celebrating all the nasty weather, excessive eating and drinking, impromptu bike maintenance, and generally messing about on bikes with friends.

I came up with the first line first; always a good start. I wanted to have a sparse, slightly gloomy sounding verse so that I could pair it with an excessively happy chorus. Of course It just would work without rain ambience and bike and sheep noises. Next up came the bass line; I’ve never really played slap bass before (on my Sire Marcus Miller M2 bass), but I am pretty happy with the result – I’m sure it sounds better than when I played it due to the wonders of Logic Pro’s flex pitch editor! Next was the guitar, which is very simple. Drums are courtesy of Logic’s excellent Drummer instrument, which I got to follow my bass part in places. I had quite a lot of lyrics for the chorus, and despite the 130bpm tempo, it manages to sound fairly leisurely. The timing of those lyrics gave me a pattern which led to a melody, which led to some very basic chords, and voila, one functioning chorus!

I’ve been very keen to try out Synthesizer V, which I had bought at fair expense earlier this year, only to find that it’s borderline unusable in DAWs like Logic. However with a little perseverance I found it was workable so long as I didn’t even consider touching the tempo. This gave me the first set of vocals – two backing lines that I made in a similar style to how I worked in Tailwind, except with these synthetic voices. I had planned to sing the main parts myself, but found it just really didn’t work, so I enlisted the help of Lucas H on Fiverr who did a great job with a quick turnaround. With all these working together, I’ve ended up with 5 vocal parts in some places, and it makes for a great ensemble sound that I wasn’t quite expecting, but I’m very happy with.

I don’t care if it’s raining,
get back on your bike
I know you’re hung over
from drinking last night
But that’s not my problem
there’s mountains to ride
and there’s no way I’m
letting you stay inside

Sheep getting restless
and puddles so deep
there’s mud to my elbows
and I’ve had no sleep
but I don’t care
‘cos we’re here to have fun
to every last drop
of this liquid Welsh sun

There’s mud and there’s sheep and there’s rides with our friends
There’s banoffee and T-shirts and hills without end
There’s maps and confusion and roads to nowhere
There’s mud and there’s bikes and that’s why we are here

No punctured excuses
or unspoken wheels
we’re chained to the bars
as we grind up the hills.
We’re spinning for summits
and covered in grime
leaving tread on the tracks
of a great mountain climb

There’s mud and there’s sheep and there’s rides with our friends
There’s banoffee and T-shirts and hills without end
There’s maps and confusion and roads to nowhere
There’s mud and there’s bikes and that’s why we are here

Pedal, pedal... up the hills
Pedal, pedal... up the hills

There’s mud and there’s sheep and there’s rides with our friends
We always come back here, again and again
There’s mountains and rivers and crates of cold beer
There’s mud and there’s bikes and that’s why we are here

Laravel duplicate key error despite unique validation

In a Laravel API, it’s really common to create users with an endpoint like this in a user controller:

public function store(Request $request): UserResource|JsonResponse
{
    $validator = Validator::make(
        $request->all(),
        [
            'email' => 'required|string|max:255|email|unique:users',
            'name'  => 'required|string|max:255',
        ],
        [
            'email.unique' => 'That email address already has an account.',
        ]
    );
    if ($validator->fails()) {
        return response()->json(
            [
                'error'   => true,
                'message' => $validator->errors()->all(),
            ],
            Response::HTTP_UNPROCESSABLE_ENTITY
        );
    }
    $user = User::create(
        $request->only(
            [
                'email',
                'name',
            ]
        )
    );Code language: PHP (php)

There’s a problem here though – that unique validation on the email field is subject to a race condition. If two requests are received very close together, both can pass validation, but then the second one will fail with a duplicate key error on the User::create call. While that sounds unlikely, it happens for real sometimes, and you’ll see something like this in your web logs when it does:

192.168.0.1 - - [06/Oct/2023:07:08:54 +0000] "POST /users/ HTTP/2.0" 201 1276 "-" "okhttp/4.9.2"
192.168.0.1 - - [06/Oct/2023:07:08:55 +0000] "POST /users/ HTTP/2.0" 500 17841 "-" "okhttp/4.9.2"Code language: JavaScript (javascript)

The 201 response is a successful creation, but it’s followed a second later by a 500 failure for the duplicate request. The Laravel log will then contain one of these:

[2023-10-06 07:08:55] staging.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'user@example.com'
 for key 'users.users_email_unique' (Connection: mysql, SQL: insert into `users` (`email`, `name`) values (user@example.com, Test)Code language: JavaScript (javascript)

To deal with that we can trap the creation error, and return an error response that looks the same as the validation error:

try {
    $user = User::create(
        $request->only(
            [
                'email',
                'name',
            ]
        )
    );
} catch (QueryException $e) {
    //1062 is the MySQL code for duplicate key
    if ($e->errorInfo[1] !== 1062) {
        //Rethrow anything except a duplicate key error
        throw $e;
    }
    return response()->json(
        [
            'error'   => true,
            'message' => 'That email address already has an account.',
        ],
        Response::HTTP_UNPROCESSABLE_ENTITY
    );
}Code language: PHP (php)

This way, as far as the client is concerned, it was a straightforward validation failure with an appropriate 422 error code, and we don’t get spurious 500s clogging up our error logs.