Skip to content

Commit bccc8a5

Browse files
author
Brian Chen
authored
Surface transaction errors in browser (#2017)
1 parent 13cdd14 commit bccc8a5

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

packages/firestore/src/platform_browser/webchannel_connection.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import { DatabaseId, DatabaseInfo } from '../core/database_info';
3131
import { SDK_VERSION } from '../core/version';
3232
import { Connection, Stream } from '../remote/connection';
3333
import {
34-
mapCodeFromHttpStatus,
35-
mapCodeFromRpcStatus
34+
mapCodeFromRpcStatus,
35+
mapCodeFromHttpResponseErrorStatus
3636
} from '../remote/rpc_error';
3737
import { StreamBridge } from '../remote/stream_bridge';
3838
import { assert, fail } from '../util/assert';
@@ -123,12 +123,29 @@ export class WebChannelConnection implements Connection {
123123
xhr.getResponseText()
124124
);
125125
if (status > 0) {
126-
reject(
127-
new FirestoreError(
128-
mapCodeFromHttpStatus(status),
129-
'Server responded with status ' + xhr.getStatusText()
130-
)
131-
);
126+
const responseError = xhr.getResponseJson().error;
127+
if (
128+
!!responseError &&
129+
!!responseError.status &&
130+
!!responseError.message
131+
) {
132+
const firestoreErrorCode = mapCodeFromHttpResponseErrorStatus(
133+
responseError.status
134+
);
135+
reject(
136+
new FirestoreError(
137+
firestoreErrorCode,
138+
responseError.message
139+
)
140+
);
141+
} else {
142+
reject(
143+
new FirestoreError(
144+
Code.UNKNOWN,
145+
'Server responded with status ' + xhr.getStatus()
146+
)
147+
);
148+
}
132149
} else {
133150
// If we received an HTTP_ERROR but there's no status code,
134151
// it's most probably a connection issue

packages/firestore/src/remote/rpc_error.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,18 @@ export function mapCodeFromHttpStatus(status: number): Code {
298298
return Code.UNKNOWN;
299299
}
300300
}
301+
302+
/**
303+
* Converts an HTTP response's error status to the equivalent error code.
304+
*
305+
* @param status An HTTP error response status ("FAILED_PRECONDITION",
306+
* "UNKNOWN", etc.)
307+
* @returns The equivalent Code. Non-matching responses are mapped to
308+
* Code.UNKNOWN.
309+
*/
310+
export function mapCodeFromHttpResponseErrorStatus(status: string): Code {
311+
const serverError = status.toLowerCase().replace('_', '-');
312+
return Object.values(Code).indexOf(serverError as Code) >= 0
313+
? (serverError as Code)
314+
: Code.UNKNOWN;
315+
}

0 commit comments

Comments
 (0)