Frontend errors: use `ErrorBoundary` for error handling

# Overview

As part of our effort to improve the frontend logs management in `CustomersDot`, as well as reduce code duplication and manual error handling, provide more useful and consistent error info to our users, we will implement a [_holistic_ approach to errors](https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/2279) which consists of 2 parts:

- [Centralise Sentry logs management](https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/3349)
- Use `ErrorBoundary` for error handling (current)

The 2 parts have been individuated in a **[previous research with PoC](https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/2935)** which helped define the approach. Some use cases are presented [here](https://vue-demo.xyz/).

##### Use `ErrorBoundary` Component for displaying UI errors

Advantages of `ErrorBoundary` Component are:

- follows a standard approach in the industry, see [React's ErrorBoundaries](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html#introducing-error-boundaries)
- implements our values of [boring solutions](https://about.gitlab.com/handbook/values/#boring-solutions): it leverages [Vue errorCaptured hook](https://vuejs.org/v2/api/#errorCaptured)
- increases maintainability: we rely on `GlAlert` for displaying errors, we can encapsulate its usage in the `ErrorBoundary`
- allows moving error messages definitions to a more central level (app or global configuration)

We will measure success by:

- reducing (eliminating) manual toggling of errors

<details>
<summary>The approach is also good for splitting responsibilities between layers and increasing the flexibility fo our error displaying management </summary>

- **responsibility** comes in terms of delegation when the UI/UX of errors for a (more or less long) chain of components can be handled at a centralized place. An `ErrorBoundary` Component is a quasi [render-less component](https://adamwathan.me/renderless-components-in-vuejs/), that aims to help in scenarios where data and behaviors are often the same. Analog to this is the use of services such as `API`, `Vuex`, that lift from the component the burden of managing communication or data flow
- **flexibility** comes in terms of configuration. An `ErrorBoundary` Component is general enough to account for the majority of cases while also being close enough to the app where it's used to adapt to more specific cases where the desired behavior might need to change or adapt

</details>

##### Scenarios to consider

<details>
<summary>Errors coming from the ~backend are not suitable for being displayed to the user</summary>

We had [some cases](https://gitlab.com/gitlab-org/gitlab/-/issues/331148) where the error received from the ~backend was not offering much information to the ~frontend. The suggested approach will allow us:

- in the short run, to account for such cases in a more flexible way
- in the long run, to establish a way where the ~backend communicates with the ~frontend using codes (e.g. `UNSUCCESSFUL_X_Y_Z` instead of string literals, an approach that [already proved useful](https://gitlab.com/gitlab-org/gitlab/-/issues/327255#note_556782292))

</details>

# Implementation plan

[Sentry Vue Integration](https://docs.sentry.io/platforms/javascript/guides/vue/configuration/integrations/default/) [attaches the `errorHandlder` to our Vue instance](https://github.com/getsentry/sentry-javascript/blob/master/packages/integrations/src/vue.ts#L390). This will catch and log all the errors generated at runtime to the specified Sentry API.

After creating the `ErrorBoundary` Component, we should tackle each application one by one.

| Step | MR |
|-|-|
| Create the `ErroBoundary` Component (an [example](https://gitlab.com/agulina/vue-demo/-/blob/main/src/services/error_boundary.vue)) |  _tdb_ |
| Use `ErrorBoundary` in [`add_seats.vue`](https://gitlab.com/gitlab-org/customers-gitlab-com/-/blob/662f889b066e628c8b5db7aec0b8099d72927ff2/app/frontend/javascripts/subscription/components/add_seats.vue) | _tdb_ |

# Other resources

- the Draft MR: gitlab-org/customers-gitlab-com!2935
- a video showing the approaches in the demo app: [link to drive](https://drive.google.com/file/d/1yBdT51vIP-DEdL54QOZoIgPSFSOa-rhu/view?usp=sharing)
- a video for some more specific cases: [link to drive](https://drive.google.com/file/d/1KXNUX-CCU-MXot0q6aC9fic9fY7BjspR/view?usp=sharing)
- a video for some more specific cases: [link to drive](https://drive.google.com/file/d/1RBaJ7bDezuXcJblWgImY9uTDdCfeF3TS/view?usp=sharing)

Story points: 5.0