11import { DiffPart , JumpURLFetcher } from '@sourcegraph/codeintellify'
22import { Controller } from '@sourcegraph/extensions-client-common/lib/client/controller'
33import { 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'
55import { ajax , AjaxResponse } from 'rxjs/ajax'
66import { catchError , map , tap } from 'rxjs/operators'
77import { 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'
2525import { memoizeObservable } from '../util/memoize'
2626import { toAbsoluteBlobURL } from '../util/url'
27- import { normalizeAjaxError } from './errors'
27+ import { normalizeAjaxError , NoSourcegraphURLError } from './errors'
2828import { getHeaders } from './headers'
2929
3030export 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