That, incidentally, is why key functions (aka native support for decorate-sort-undecorate) is so convenient: rather than a fiddly and error prone comparator, the key function just returns a comparable (a value or composition of values).
A good alternative for statically typed languages is to have the comparison result be a proper sum type, and provide ways to generate and compose comparisons e.g. Haskell or Rust's Ordering (and Ord trait / typeclass).