Replace send method usage

Send is largely a duplicate of the logic that is found in fetch and
fetchJSON, but combines both parsed and naked Response logic and has
slightly different error handling. To avoid confusion and reduce
duplication we remove send() method and replace it with fetch or
fetchJSON depending on whether response needs to be parsed or not.

The difference between send() and fetch() is behaviour when receiving
non-200 error code. send() will show an error message with an error,
while fetch returns response as-is to be parsed by the caller. To
account for this we set reportServerError to true for all calls to
fetch. fetchJSON() has the same server-error handling as send, so that
is not needed, in cases where `parseResponse: true`.

Some methods have wrong return types: don't account for the fact that
response can be undefined if parsing is required. We fix the return type
annotation and additionally fix callsites, if they don't properly handle
the null value.

AddAccountSSHKey and AddAccountGPGKey similarly were reimplementing
logic of fetchJSON, so instead we pass throwingErrorCallback to achieve
the same result.

Google-Bug-Id: b/297849592
Release-Notes: skip
Change-Id: I8e636a1423d950c0b3e9e64b8b61a20c8342764f
diff --git a/polygerrit-ui/app/test/mocks/gr-rest-api_mock.ts b/polygerrit-ui/app/test/mocks/gr-rest-api_mock.ts
index 3314ce4..efa9631 100644
--- a/polygerrit-ui/app/test/mocks/gr-rest-api_mock.ts
+++ b/polygerrit-ui/app/test/mocks/gr-rest-api_mock.ts
@@ -169,7 +169,7 @@
     return Promise.resolve(new Response());
   },
   finalize(): void {},
-  generateAccountHttpPassword(): Promise<Password> {
+  generateAccountHttpPassword(): Promise<Password | undefined> {
     return Promise.resolve('asdf');
   },
   getAccount(): Promise<AccountDetailInfo | undefined> {
@@ -496,7 +496,7 @@
   saveGroupDescription(): Promise<Response> {
     return Promise.resolve(new Response());
   },
-  saveGroupMember(): Promise<AccountInfo> {
+  saveGroupMember(): Promise<AccountInfo | undefined> {
     return Promise.resolve({});
   },
   saveGroupName(): Promise<Response> {
@@ -518,7 +518,7 @@
   saveRepoConfig(): Promise<Response> {
     return Promise.resolve(new Response());
   },
-  saveWatchedProjects(): Promise<ProjectWatchInfo[]> {
+  saveWatchedProjects(): Promise<ProjectWatchInfo[] | undefined> {
     return Promise.resolve([]);
   },
   send() {
@@ -558,7 +558,7 @@
   setRepoAccessRights(): Promise<Response> {
     return Promise.resolve(new Response());
   },
-  setRepoAccessRightsForReview(): Promise<ChangeInfo> {
+  setRepoAccessRightsForReview(): Promise<ChangeInfo | undefined> {
     throw new Error('setRepoAccessRightsForReview() not implemented by mock.');
   },
   setRepoHead(): Promise<Response> {