Repository: microsoft/nni
File: ts/nni_manager/training_service/reusable/aml/amlClient.ts (TypeScript)

Code before:
    public sendCommand(message: string): void {
        if (this.pythonShellClient === undefined) {
            throw Error('python shell client not initialized!');
        }
        this.pythonShellClient.send(`command:${message}`);
    }

    public receiveCommand(): Promise<any> {
        const deferred: Deferred<any> = new Deferred<any>();
        if (this.pythonShellClient === undefined) {
            throw Error('python shell client not initialized!');
        }
        this.pythonShellClient.send('receive');
        this.pythonShellClient.on('message', (command: any) => {
            const message = this.parseContent('receive', command);
            if (message !== '') {
                deferred.resolve(JSON.parse(message))
            }
        });
        this.monitorError(this.pythonShellClient, deferred);
        return deferred.promise;
    }
    
    // Monitor error information in aml python shell client
    private monitorError(pythonShellClient: PythonShell, deferred: Deferred<any>): void {
        pythonShellClient.on('stderr', function (error: any) {
            // FIXME: The error will only appear in console.
            // Still need to find a way to put them into logs.
            console.error(`Python process stderr: ${error}`);
        });
        pythonShellClient.on('error', function (error: any) {
            console.error(`Python process fires error: ${error}`);
            deferred.reject(error || new Error('AML client Python process unknown error.'));
        });
        pythonShellClient.on('close', function (error: any) {
            // The error here could be undefined.
            console.error(`Python process fires unexpected close signal: ${error}`);
            deferred.reject(error || new Error('AML client Python process unknown error.'));
        });
    }
    
    // Parse command content, command format is {head}:{content}
    public parseContent(head: string, command: string): string {
        const items = command.split(':');
        if (items[0] === head) {
            return command.slice(head.length + 1);
        }
        return '';
    }
}


Review comment (suggestion):
```javascript
on('stderr', (chunk: any) => {
```

Code after:
    public sendCommand(message: string): void {
        if (this.pythonShellClient === undefined) {
            throw Error('python shell client not initialized!');
        }
        this.pythonShellClient.send(`command:${message}`);
    }

    public receiveCommand(): Promise<any> {
        const deferred: Deferred<any> = new Deferred<any>();
        if (this.pythonShellClient === undefined) {
            throw Error('python shell client not initialized!');
        }
        this.pythonShellClient.send('receive');
        this.pythonShellClient.on('message', (command: any) => {
            const message = this.parseContent('receive', command);
            if (message !== '') {
                deferred.resolve(JSON.parse(message))
            }
        });
        this.monitorError(this.pythonShellClient, deferred);
        return deferred.promise;
    }
    
    // Monitor error information in aml python shell client
    private monitorError(pythonShellClient: PythonShell, deferred: Deferred<any>): void {
        pythonShellClient.on('stderr', function (chunk: any) {
            // FIXME: The error will only appear in console.
            // Still need to find a way to put them into logs.
            console.error(`Python process stderr: ${chunk}`);
        });
        pythonShellClient.on('error', function (error: Error) {
            console.error(`Python process fires error: ${error}`);
            deferred.reject(error);
        });
        pythonShellClient.on('close', function () {
            deferred.reject(new Error('AML client Python process unknown error.'));
        });
    }
    
    // Parse command content, command format is {head}:{content}
    public parseContent(head: string, command: string): string {
        const items = command.split(':');
        if (items[0] === head) {
            return command.slice(head.length + 1);
        }
        return '';
    }
}