SanderRonde / phpstan-vscode

PHPStan plugin for VSCode
https://marketplace.visualstudio.com/items?itemName=SanderRonde.phpstan-vscode
MIT License
37 stars 7 forks source link

Language Server Crashing #76

Closed joeworkman closed 2 months ago

joeworkman commented 2 months ago

I updated the extension today and am getting an error that the language server is crashing. Here are the details from the output.

[server] Language server ready
/Users/joeworkman/.vscode/extensions/sanderronde.phpstan-vscode-3.1.4/out/server.js:74
`+i)}function Ri(e,t,i,n,r){if(e.listenerCount("wsClientError")){let s=new Error(r);Error.captureStackTrace(s,Ri),e.emit("wsClientError",s,i,t)}else zn(i,n,r)}});var nn=ve(Il());var ts=ve(require("fs/promises")),Al=ve(require("crypto")),Ol=require("fs");function Ll(e){if(e)throw new Error(`Value of type '${typeof e}' was not expected and should be unreachable`)}async function Ti(e){await new Promise(t=>setTimeout(t,e))}async function ql(e,t,i){let n=0;for(;n<e;){let r=i();if(r!==null)return r;let s=Math.min(t,e-n);await Ti(s),n+=s}return null}function Ml(){return new Promise(e=>{let t=new Promise(i=>{e({resolve:i,get promise(){return t}})})})}function Ia(e){let t=null,i=new Promise(n=>{t=setTimeout(()=>{n(e.onTimeout())},e.timeout),e.promise.then(r=>{n(r),t&&clearTimeout(t)})});return{dispose:()=>t?clearTimeout(t):void 0,promise:i}}function Fl(e){let t=!1;return e.then(()=>{t=!0}),{promise:e,get done(){return t}}}async function Aa(e){try{return await ts.access(e,Ol.constants.F_OK),!0}catch{return!1}}async function xR(e){try{return await ts.readFile(e,"utf-8")}catch{return null}}async function Ul(e){let t=await xR(e);return t===null?null:JSON.parse(t)}function Nn(e){return Al.createHash("md5").update(e).digest("hex")}function jl(e){let t={};for(let[i,n]of e)t[i]=n;return t}var ti=ve(es()),Hl=new ti.NotificationType("phpstan.watcher"),Wl=new ti.NotificationType("phpstan.command"),Bl=new ti.NotificationType("phpstan.log"),Ct=new ti.NotificationType("phpstan.statusBar"),wn=new ti.NotificationType("phpstan.error"),Vl=new ti.NotificationType("phpstan.spawner"),Oa=new ti.NotificationType("phpstan.phpstanPro");async function ie(e,t,...i){i=[t,...i],console.log(i.join(" ")),await e.sendNotification(Bl,{data:i.map(n=>String(n))})}function Pt(e){return`[check:${e.id}]`}var La="[fixer-manager]",qa="[file-watcher]",Gl="[error]",Ma="[hover-provider]",ki="[server]",Gi="[pro]";var is=require("path"),Fa="sanderronde.phpstan-vscode",Ua=!0,ja=is.join(__dirname,".."),$l=6e4,Kl=50,zl=is.join(ja,"php/TreeFetcher.php"),Yl=is.join(ja,"php/config.neon"),Ql=is.join(ja,"php/config.2.neon"),Xl=1e3*60*15,Jl=100,$i={shell:process.platform==="win32",windowsVerbatimArguments:!0};async function le(e){let t=await e.workspaceFolders.get(),i=t?.default.toString(),n=await e.connection.workspace.getConfiguration({scopeUri:i,section:"phpstan"});return{...n,binPath:Dt(n.binPath,t),binCommand:n.binCommand.map(r=>Dt(r,t)),configFile:Dt(n.configFile,t),paths:jl(Object.entries(n.paths).map(([r,s])=>[Dt(r,t),Dt(s,t)])),proTmpDir:Dt(n.proTmpDir,t),rootDir:Dt(n.rootDir,t),options:n.options.map(r=>Dt(r,t)),ignoreErrors:n.ignoreErrors.map(r=>r instanceof RegExp?new RegExp(Dt(r.source,t)):Dt(r,t))}}function Dt(e,t){return e.replace(/\${workspaceFolder(?::(\w+))?}/g,(i,n)=>{if(n){if(!t)throw new Error("workspaceFolder:name is not set but is used in a variable");let s=t[n];if(!s)throw new Error(`workspaceFolder:${n} is not set but is used in a variable`);return s.fsPath}let r=t?.default;if(!r)throw new Error("workspaceFolder is not set but is used in a variable");return r.fsPath})}async function jt(e,...t){await e.sendNotification(Wl,{commandName:t[0],commandArgs:t.slice(1)})}var Zl=new Set;async function Ki(e,t,...i){await ie(e,Gl,t,...i),!Zl.has(t)&&(Ei(e,t),Zl.add(t))}function Ei(e,t,i=[]){e.window.showErrorMessage(t,...i.map(({title:n})=>({title:n}))).then(n=>{if(!i||!n)return;i.find(s=>s.title===n.title)?.callback()})}var Se=class e{constructor(t,i,n=null){this.status=t;this.value=i;this.error=n}static success(t){return new e("Success",t)}static killed(){return new e("Killed",null)}static canceled(){return new e("Canceled",null)}static error(t){return new e("Error",null,t)}success(){return this.status==="Success"}chain(t){return this.success()?e.success(t(this.value)):this}cast(){return this}};var eh=ve(require("fs/promises")),th=require("fs"),In=ve(require("path")),zi=ve(require("os")),He=class e{static async applyPathMapping(t,i){return(await this.getPathMapper(t))(i)}static escapeFilePath(t){return zi.platform()!=="win32"||t.indexOf(" ")!==-1&&(t='"'+t+'"'),t}static async getPathMapper(t){let i=(await le(t)).paths??{};return(n,r=!1)=>{if(Object.keys(i).length===0)return n;let s=n.replace(/^~/,zi.homedir());for(let[o,h]of Object.entries(i)){let[l,d]=r?[h,o]:[o,h],g=l.replace(/^~/,zi.homedir());if(s.startsWith(g))return s.replace(g,d.replace(/^~/,zi.homedir()))}return n}}static async _fileIfExists(t){try{return await eh.access(t,th.constants.R_OK),t}catch{return null}}static _getAbsolutePath(t,i){return t?In.isAbsolute(t)?t:i?In.join(i,t):null:null}static async _getConfigFile(t,i){let n=await le(t),r=n.configFile?n.configFile.split(",").map(s=>s.trim()).map(s=>this._getAbsolutePath(s,i)):[];for(let s of r)if(s&&await this._fileIfExists(s))return s;return n.configFile&&await Ki(t.connection,`PHPStan: failed to find config file in "${n.configFile}"`),null}static async getCwd(t){let i=(await t.workspaceFolders.get())?.default,n=await le(t),r=this._getAbsolutePath(n.rootDir,i?.fsPath??void 0)||i?.fsPath;return r&&!await this._fileIfExists(r)?(await Ki(t.connection,`PHPStan: rootDir "${r}" does not exist`),null):r||(await Ki(t.connection,"PHPStan: failed to get CWD","workspaceRoot=",i?.fsPath??"undefined"),null)}static async getBinConfig(t,i){let n=await le(t),s=this._getAbsolutePath(n.binPath,i)??In.join(i,"vendor/bin/phpstan");s.startsWith("~")&&(s=`${process.env.HOME??"~"}${s.slice(1)}`);let o=n.binCommand;if(!s&&(!o||o.length===0))return await Ki(t.connection,"PHPStan: failed to find binary path"),null;if((!o||o.length===0)&&!await this._fileIfExists(s))return await Ki(t.connection,`PHPStan: failed to find binary at "${s}"`),null;if(o?.length){let[h,...l]=o;return h.startsWith("~")&&(h=`${process.env.HOME??"~"}${h.slice(1)}`),{binCmd:h,binPath:null,initialArgs:l}}return{binCmd:null,binPath:s,initialArgs:[]}}static async collectConfiguration(t){let i=await le(t),n=await this.getCwd(t);if(!n)return null;let r=await this.getBinConfig(t,n);if(!r)return null;let s=await this._getConfigFile(t,n);return s?{cwd:n,configFile:s,remoteConfigFile:s?await e.applyPathMapping(t,s):null,args:i.options??[],memoryLimit:i.memoryLimit,binStr:r.binCmd?r.binCmd:e.escapeFilePath(r.binPath),...r}:null}static async getArgs(t,i,n){let r=[...i.initialArgs,"analyse"];return i.remoteConfigFile?r.push("-c",e.escapeFilePath(i.remoteConfigFile)):i.configFile&&r.push("-c",i.configFile),r.push("--error-format=json","--no-interaction",`--memory-limit=${i.memoryLimit}`),n||r.push("--no-progress"),r.push(...i.args),await t.hooks.provider.transformArgs(i,[i.binStr,...r])}};var ih=ve(require("os")),ns=class{constructor(t){this._classConfig=t;this._cancelled=!1;this._disposables=new Set}static escapeFilePath(t){return ih.platform()!=="win32"||t.indexOf(" ")!==-1&&(t='"'+t+'"'),t}_kill(t){return Promise.race([new Promise(i=>{let n=!1;t.once("exit",()=>{n=!0,i()}),t.kill("SIGINT"),setTimeout(()=>{n||(t.kill("SIGTERM"),setTimeout(()=>{n||t.kill("SIGKILL")},2e3))},2e3)}),Ti(1e3*10)])}_createOutputCapturer(t,i,n){let r="";return t[i]?.on("data",s=>{let o=s.toString("utf-8"),h=n?[...o.matchAll(/(\d+)\/(\d+)\s+\[.*?\]\s+(\d+)%/g)]:[];if(h.length){let[,d,g,T]=h[h.length-1];n({done:parseInt(d,10),total:parseInt(g,10),percentage:parseInt(T,10)});return}/\x1b\[(\d+)/g.test(o)||(r+=o)}),()=>r}async _showIgnoredErrorRegexWarning(t){let i="Fix in settings";(await this._classConfig.connection.window.showErrorMessage(`To-ignore error "${t}" is not a valid regular expression`,{title:i},{title:"Close"}))?.title===i&&await jt(this._classConfig.connection,"workbench.action.openSettings","phpstan.ignoreErrors")}_filterIgnoredErrors(t,i){for(let n of i){let r=(()=>{if(n instanceof RegExp)return n;try{return new RegExp(n)}catch{return this._showIgnoredErrorRegexWarning(n),null}})();r&&(t=t.filter(s=>!r.test(s)))}return t}async _spawnProcess(t,i,n){let[r,...s]=await He.getArgs(this._classConfig,t,n);return await ie(this._classConfig.connection,Pt(i),"Spawning PHPStan with the following configuration: ",JSON.stringify({binStr:r,args:s})),await this._classConfig
[Error - 11:49:40 AM] The PHPStan Language Server server crashed 5 times in the last 3 minutes. The server will not be restarted. See the output for more information.

Its odd that JS is output instead of the actual error. Anyone have any ideas that I can try?

SanderRonde commented 2 months ago

That's very odd indeed. Can you try the obvious of deleting and re-installing the extension? This could very well be a somehow-corrupted server.js file. And which version of VSCode are you running? What happens if you run the language server by itself (node path/to/language/server.js --stdio)? If you see no output that's good (it's waiting for input).

joeworkman commented 2 months ago

Reinstall fixed it. Thanks!