@@ -4,7 +4,7 @@ import * as path from 'path';
44import * as os from 'os' ;
55import * as fs from 'fs' ;
66import { workspace , extensions , ExtensionContext , window , StatusBarAlignment , commands , ViewColumn , Uri , CancellationToken , TextDocumentContentProvider , TextEditor , WorkspaceConfiguration , languages , IndentAction , ProgressLocation , InputBoxOptions , Selection , Position , EventEmitter } from 'vscode' ;
7- import { ExecuteCommandParams , ExecuteCommandRequest , LanguageClient , LanguageClientOptions , RevealOutputChannelOn , Position as LSPosition , Location as LSLocation , StreamInfo , VersionedTextDocumentIdentifier } from 'vscode-languageclient' ;
7+ import { ExecuteCommandParams , ExecuteCommandRequest , LanguageClient , LanguageClientOptions , RevealOutputChannelOn , Position as LSPosition , Location as LSLocation , StreamInfo , VersionedTextDocumentIdentifier , ErrorHandler , Message , ErrorAction , CloseAction , InitializationFailedHandler } from 'vscode-languageclient' ;
88import { onExtensionChange , collectJavaExtensions } from './plugin' ;
99import { prepareExecutable , awaitServerConnection } from './javaServerStarter' ;
1010import * as requirements from './requirements' ;
@@ -27,8 +27,47 @@ let lastStatus;
2727let languageClient : LanguageClient ;
2828const jdtEventEmitter = new EventEmitter < Uri > ( ) ;
2929const cleanWorkspaceFileName = '.cleanWorkspace' ;
30+ const extensionName = 'Language Support for Java' ;
3031let clientLogFile ;
3132
33+ class ClientErrorHandler implements ErrorHandler {
34+ private restarts : number [ ] ;
35+
36+ constructor ( private name : string ) {
37+ this . restarts = [ ] ;
38+ }
39+
40+ public error ( _error : Error , _message : Message , count : number ) : ErrorAction {
41+ if ( count && count <= 3 ) {
42+ logger . error ( `${ this . name } server encountered error: ${ _message } , ${ _error && _error . toString ( ) } ` ) ;
43+ return ErrorAction . Continue ;
44+ }
45+
46+ logger . error ( `${ this . name } server encountered error and will shut down: ${ _message } , ${ _error && _error . toString ( ) } ` ) ;
47+ return ErrorAction . Shutdown ;
48+ }
49+
50+ public closed ( ) : CloseAction {
51+ this . restarts . push ( Date . now ( ) ) ;
52+ if ( this . restarts . length < 5 ) {
53+ logger . error ( `The ${ this . name } server crashed and will restart.` ) ;
54+ return CloseAction . Restart ;
55+ } else {
56+ const diff = this . restarts [ this . restarts . length - 1 ] - this . restarts [ 0 ] ;
57+ if ( diff <= 3 * 60 * 1000 ) {
58+ const message = `The ${ this . name } server crashed 5 times in the last 3 minutes. The server will not be restarted.` ;
59+ logger . error ( message ) ;
60+ window . showErrorMessage ( message ) ;
61+ return CloseAction . DoNotRestart ;
62+ }
63+
64+ logger . error ( `The ${ this . name } server crashed and will restart.` ) ;
65+ this . restarts . shift ( ) ;
66+ return CloseAction . Restart ;
67+ }
68+ }
69+ }
70+
3271export function activate ( context : ExtensionContext ) : Promise < ExtensionAPI > {
3372
3473 let storagePath = context . storagePath ;
@@ -84,7 +123,12 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
84123 } ,
85124 triggerFiles : getTriggerFiles ( )
86125 } ,
87- revealOutputChannelOn : RevealOutputChannelOn . Never
126+ revealOutputChannelOn : RevealOutputChannelOn . Never ,
127+ errorHandler : new ClientErrorHandler ( extensionName ) ,
128+ initializationFailedHandler : error => {
129+ logger . error ( `Failed to initialize ${ extensionName } due to ${ error && error . toString ( ) } ` ) ;
130+ return true ;
131+ }
88132 } ;
89133
90134 const item = window . createStatusBarItem ( StatusBarAlignment . Right , Number . MIN_VALUE ) ;
@@ -114,7 +158,7 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
114158 }
115159
116160 // Create the language client and start the client.
117- languageClient = new LanguageClient ( 'java' , 'Language Support for Java' , serverOptions , clientOptions ) ;
161+ languageClient = new LanguageClient ( 'java' , extensionName , serverOptions , clientOptions ) ;
118162 languageClient . registerProposedFeatures ( ) ;
119163
120164 languageClient . onReady ( ) . then ( ( ) => {
0 commit comments