You could try the Huber loss function. It penalizes close predictions more than predictions that are very wrong.
Using the usual notation for Huber Less, define $a_i$ as your residual, $Y_i - \hat{Y}_{i}$. Huber loss is defined as
$$ L_\delta(a) = \begin{cases}
\frac{1}{2} a^2, & \text{for $|a| < \delta$} \\
\delta * (|a| - \frac{1}{2}\delta), & \text{for $|a| \geq \delta$}
\end{cases}$$
You define a threshold of "closeness", $\delta$. If your prediction is within this threshold, your loss is quadratic. If your prediction is outside of this threshold, your loss is linear. This let's the model prioritize fitting points that your model is close to getting correct and de-prioritize outliers. If you want to de-emphasize outliers even further, you could increase the polynomial degree in the case when $|a| < \delta$ and/or decrease the polynomial degree when $|a| \geq \delta$.
In R, you can calculate Huber Loss with the yardstick package. I'm not aware of any out-of-the-box implementations of Huber loss as a standalone metric in Python. Sklearn let's you fit linear regression with Huber Loss. but Huber Loss isn't one of sklearn's scoring metric.