<p>I have a backend with golang that talks to k8s. I want to reformulate the error response that i get from k8s and send it to the frontend.</p>
<p>I want to return a meaningful validation error messages for the user, when he add a non valid name, something already exist ...</p>
<p>And i want something generic not hardcoded in each endpoint's controller.</p>
<p>I am using <code>kubernetes/client-go</code>.</p>
<ol>
<li><strong>First error</strong>:</li>
</ol>
<p>For example lets say i want to add a hotel to the <code>etcd</code>, when i try to add the hotel's name: hotel123,  that's already exist.</p>
<ul>
<li>I get this error message: <code>\&quot;hotel123\&quot; already exists</code>.</li>
<li>What i want : <code>hotel123 already exists</code>.</li>
</ul>
<ol start="2">
<li><strong>second error</strong>:</li>
</ol>
<p>For example lets say i want to add a hotel to the <code>etcd</code>, when i try to add the hotel name: hotel_123, that's alerady exist.</p>
<ul>
<li>I get this error message: <code>\&quot;hotel_123\&quot; is invalid, Invalid value: \&quot;hotel_123\&quot;...</code></li>
<li>What i want: <code>hotel_123 is invalid</code></li>
</ul>
<p>How to return a custom user friendly error message ?</p>
<p>PS: i have multiple functions, so the validation should be generic.</p>

<p>In general (although there are workarounds), if you want to trap an error in order to return a more useful error, you want to ensure the following conditions are met:</p>
<ol>
<li>The error you're trapping has a <a href="https://sourcegraph.com/github.com/kubernetes/client-go/-/blob/tools/clientcmd/validation.go" rel="nofollow noreferrer">meaningful type</a></li>
<li>You're using go version &gt;= 1.13 which ships with <a href="https://go.dev/blog/go1.13-errors" rel="nofollow noreferrer">useful helper functions</a></li>
</ol>
<p>In the following example I'm trying to read a config file that doesn't exist. My code checks that the error returned is a <code>fs.PathError</code> and then throws it's own more useful error. You can extend this general idea to your use case.</p>
<pre><code>package main

import (
    &quot;errors&quot;
    &quot;fmt&quot;
    &quot;io/fs&quot;

    &quot;k8s.io/client-go/tools/clientcmd&quot;
)

func main() {

    var myError error
    config, originalError := clientcmd.BuildConfigFromFlags(&quot;&quot;, &quot;/some/path/that/doesnt/exist&quot;)
    if originalError != nil {

        var pathError *fs.PathError

        switch {
        case errors.As(originalError, &amp;pathError):

            myError = fmt.Errorf(&quot;there is no config file at %s&quot;, originalError.(*fs.PathError).Path)

        default:

            myError = fmt.Errorf(&quot;there was an error and it's type was %T&quot;, originalError)

        }

        fmt.Printf(&quot;%#v&quot;, myError)

    } else {

        fmt.Println(&quot;There was no error&quot;)
        fmt.Println(config)

    }

}
</code></pre>
<p>In your debugging, you will find the <code>%T</code> formatter <a href="https://pkg.go.dev/fmt" rel="nofollow noreferrer">useful</a>.</p>
<p>For your specific use-case, you can use a Regex to parse out the desired text.</p>
<p>The regex below says:</p>
<ol>
<li><code>^\W*</code> start with any non-alhpanumeric characters</li>
<li><code>(\w+)</code> capture the alphanumeric string following</li>
<li><code>\W*\s?</code> match non-alphanumeric characters</li>
<li><code>(is\sinvalid)</code> capture &quot;is invalid&quot;</li>
</ol>
<pre class="lang-golang prettyprint-override"><code>func MyError(inError error) error {
    pattern, _ := regexp.Compile(`^\W*(\w+)\W*\s?(is\sinvalid)(.*)$`)
    myErrorString := pattern.ReplaceAll([]byte(inError.Error()), []byte(&quot;$1 $2&quot;))
    return errors.New(string(myErrorString))
}
</code></pre>
<p>As seen on this playground:</p>
<p><a href="https://goplay.tools/snippet/bcZO7wa8Vnl" rel="nofollow noreferrer">https://goplay.tools/snippet/bcZO7wa8Vnl</a></p>
