forked from microsoft/FluidFramework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathodspError.ts
155 lines (138 loc) · 4.87 KB
/
odspError.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
NetworkErrorBasic,
GenericNetworkError,
NonRetryableError,
AuthorizationError,
isOnline,
createGenericNetworkError,
OnlineStatus,
} from "@fluidframework/driver-utils";
import {
DriverError,
DriverErrorType,
} from "@fluidframework/driver-definitions";
import { IOdspSocketError } from "./contracts";
import { parseAuthErrorClaims } from "./parseAuthErrorClaims";
export const offlineFetchFailureStatusCode: number = 709;
export const fetchFailureStatusCode: number = 710;
// Status code for invalid file name error in odsp driver.
export const invalidFileNameStatusCode: number = 711;
// no response, or can't parse response
export const fetchIncorrectResponse = 712;
export enum OdspErrorType {
/**
* Storage is out of space
*/
outOfStorageError = "outOfStorageError",
/**
* Invalid file name (at creation of the file)
*/
invalidFileNameError = "invalidFileNameError",
/**
* Snapshot is too big. Host application specified limit for snapshot size, and snapshot was bigger
* that that limit, thus request failed. Hosting application is expected to have fall-back behavior for
* such case.
*/
snapshotTooBig = "snapshotTooBig",
/*
* SPO admin toggle: fluid service is not enabled.
*/
fluidNotEnabled = "fluidNotEnabled",
}
/**
* Base interface for all errors and warnings
*/
export interface IOdspError {
readonly errorType: OdspErrorType;
readonly message: string;
canRetry: boolean;
online?: string;
}
export type OdspError =
| DriverError
| IOdspError;
export function createOdspNetworkError(
errorMessage: string,
statusCode?: number,
retryAfterSeconds?: number,
claims?: string,
): OdspError {
let error: OdspError;
switch (statusCode) {
case 400:
error = new GenericNetworkError(errorMessage, false, statusCode);
break;
case 401:
case 403:
error = new AuthorizationError(errorMessage, claims);
break;
case 404:
error = new NetworkErrorBasic(errorMessage, DriverErrorType.fileNotFoundOrAccessDeniedError, false);
break;
case 406:
error = new NetworkErrorBasic(errorMessage, DriverErrorType.unsupportedClientProtocolVersion, false);
break;
case 413:
error = new NonRetryableError(errorMessage, OdspErrorType.snapshotTooBig);
break;
case 414:
case invalidFileNameStatusCode:
error = new NonRetryableError(errorMessage, OdspErrorType.invalidFileNameError);
break;
case 500:
error = new GenericNetworkError(errorMessage, true);
break;
case 501:
error = new NonRetryableError(errorMessage, OdspErrorType.fluidNotEnabled);
break;
case 507:
error = new NonRetryableError(errorMessage, OdspErrorType.outOfStorageError);
break;
case offlineFetchFailureStatusCode:
error = new NetworkErrorBasic(errorMessage, DriverErrorType.offlineError, true);
break;
case fetchFailureStatusCode:
error = new NetworkErrorBasic(errorMessage, DriverErrorType.fetchFailure, true);
break;
case fetchIncorrectResponse:
error = new NetworkErrorBasic(errorMessage, DriverErrorType.incorrectServerResponse, false);
break;
default:
error = createGenericNetworkError(errorMessage, true, retryAfterSeconds, statusCode);
}
error.online = OnlineStatus[isOnline()];
return error;
}
/**
* Throws network error - an object with a bunch of network related properties
*/
export function throwOdspNetworkError(
errorMessage: string,
statusCode: number,
response?: Response,
): never {
const claims = statusCode === 401 && response?.headers ? parseAuthErrorClaims(response.headers) : undefined;
const networkError = createOdspNetworkError(
response ? `${errorMessage}, msg = ${response.statusText}, type = ${response.type}` : errorMessage,
statusCode,
undefined /* retryAfterSeconds */,
claims);
(networkError as any).sprequestguid = response?.headers ? `${response.headers.get("sprequestguid")}` : undefined;
throw networkError;
}
/**
* Returns network error based on error object from ODSP socket (IOdspSocketError)
*/
export function errorObjectFromSocketError(socketError: IOdspSocketError) {
return createOdspNetworkError(
socketError.message,
socketError.code,
socketError.retryAfter,
// TODO: When long lived token is supported for websocket then IOdspSocketError need to support
// passing "claims" value that is used to fetch new token
undefined /* claims */);
}