Skip to content
This repository was archived by the owner on Jan 22, 2019. It is now read-only.

Commit 4f57c04

Browse files
authored
fix: retry LSP requests on sourcegraph.com (#177)
1 parent e335fc6 commit 4f57c04

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

src/shared/backend/lsp.tsx

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { DiffPart, JumpURLFetcher } from '@sourcegraph/codeintellify'
22
import { Controller } from '@sourcegraph/extensions-client-common/lib/client/controller'
33
import { ConfigurationSubject, Settings } from '@sourcegraph/extensions-client-common/lib/settings'
4-
import { from, Observable, of, OperatorFunction, throwError as error } from 'rxjs'
4+
import { from, Observable, of, OperatorFunction, throwError, throwError as error } from 'rxjs'
55
import { ajax, AjaxResponse } from 'rxjs/ajax'
66
import { catchError, map, tap } from 'rxjs/operators'
77
import { HoverMerged } from 'sourcegraph/module/client/types/hover'
@@ -21,10 +21,10 @@ import {
2121
ResolvedRevSpec,
2222
RevSpec,
2323
} from '../repo'
24-
import { canFetchForURL, getModeFromPath, repoUrlCache, sourcegraphUrl } from '../util/context'
24+
import { canFetchForURL, DEFAULT_SOURCEGRAPH_URL, getModeFromPath, repoUrlCache, sourcegraphUrl } from '../util/context'
2525
import { memoizeObservable } from '../util/memoize'
2626
import { toAbsoluteBlobURL } from '../util/url'
27-
import { normalizeAjaxError } from './errors'
27+
import { normalizeAjaxError, NoSourcegraphURLError } from './errors'
2828
import { getHeaders } from './headers'
2929

3030
export interface LSPRequest {
@@ -44,27 +44,45 @@ export function isEmptyHover(hover: HoverMerged | null): boolean {
4444
return !hover || !hover.contents || (Array.isArray(hover.contents) && hover.contents.length === 0)
4545
}
4646

47-
export function sendLSPHTTPRequests(requests: any[]): Observable<any> {
48-
const urlPathHint = requests[1] && requests[1].method
49-
return ajax({
50-
method: 'POST',
51-
url: `${sourcegraphUrl}/.api/xlang/${urlPathHint || ''}`,
52-
headers: getHeaders(),
53-
crossDomain: true,
54-
withCredentials: true,
55-
body: JSON.stringify(requests),
56-
async: true,
57-
}).pipe(
58-
// Workaround for https://github.com/ReactiveX/rxjs/issues/3606
59-
tap(response => {
60-
if (response.status === 0) {
61-
throw Object.assign(new Error('Ajax status 0'), response)
62-
}
63-
}),
64-
catchError<AjaxResponse, never>(err => {
65-
normalizeAjaxError(err)
66-
throw err
67-
}),
47+
export function sendLSPHTTPRequests(requests: any[], url: string = sourcegraphUrl): Observable<any[]> {
48+
const sendTo = (urlsToTry: string[]): Observable<AjaxResponse> => {
49+
if (urlsToTry.length === 0) {
50+
return throwError(new NoSourcegraphURLError())
51+
}
52+
53+
const urlToTry = urlsToTry[0]
54+
const urlPathHint = requests[1] && requests[1].method
55+
return ajax({
56+
method: 'POST',
57+
url: `${urlToTry}/.api/xlang/${urlPathHint || ''}`,
58+
headers: getHeaders(),
59+
crossDomain: true,
60+
withCredentials: true,
61+
body: JSON.stringify(requests),
62+
async: true,
63+
}).pipe(
64+
// Workaround for https://github.com/ReactiveX/rxjs/issues/3606
65+
tap(response => {
66+
if (response.status === 0) {
67+
throw Object.assign(new Error('Ajax status 0'), response)
68+
}
69+
}),
70+
catchError(err => {
71+
if (urlsToTry.length === 1) {
72+
// We don't have any fallbacks left, so throw the most recent error.
73+
throw err
74+
} else {
75+
return sendTo(urlsToTry.slice(1))
76+
}
77+
}),
78+
catchError<AjaxResponse, never>(err => {
79+
normalizeAjaxError(err)
80+
throw err
81+
})
82+
)
83+
}
84+
85+
return sendTo([url, DEFAULT_SOURCEGRAPH_URL].filter(url => canFetchForURL(url))).pipe(
6886
map(({ response }) => response)
6987
)
7088
}

0 commit comments

Comments
 (0)