tasksfile icon indicating copy to clipboard operation
tasksfile copied to clipboard

catching errors

Open michapixel opened this issue 4 years ago • 3 comments

this is my tasksfile.js

const { sh, cli } = require('tasksfile');
const PrettyError = require('pretty-error');
const pe = new PrettyError();
// 
function node_sass (options, env) {
	let err;
	if(env === 'development' || env === 'dev') {
		try {
			sh('node-sass ./src/sass/ --output public/css/ --source-map true --source-map-contents true && postcss ./public/css/*.css --replace', {
    			async: true,
  			})
  			.catch( (e) => {
				err = new Error(e.message, e.file, e.line)
				console.error(pe.render(err))
        	});
		} catch (e) {
			err = new Error('node-sass failed COMPLETELY to compile your styles.')
			console.log(pe.render(err))
		}
	}
}
//
cli({
  node_sass
})

i'm calling this by: npx task node_sass dev now: if node-sass throws an error, i was thinking i could catch it somehow (get the scss-file that throws the error etc.) so i flagged it as async. But the error thrown in the above catch-"block" is not the one from node-sass:

{
  "status": 1,
  "file": "D:/tests/ng-sites/eleventy/src/sass/main.scss",
  "line": 9,
  "column": 1,
  "message": "File to import not found or unreadable: ../../node_modules/motion-ui/src.",
  "formatted": "Error: File to import not found or unreadable: ../../node_modules/motion-ui/src.\n        on line 9 of src/sass/main.scss\n>> @import '../../node_modules/motion-ui/src';\r\n   ^\n"
} 
Command failed: node-sass ./src/sass/ --output public/css/ --source-map true --source-map-contents true && postcss ./p
  ublic/css/*.css --replace with exit code 1

  - tasksfile.js:18 sh.catch
    D:/tests/ng-sites/eleventy/tasksfile.js:18:11

See, the first part (the object) is what i wanted to print fine.

Any way i can achieve this?

michapixel avatar Jul 08 '20 13:07 michapixel

This is most probably not the whole answer, but may help in finding the actual solution: I investigated using Tasksfile earlier this year as it felt to be such a tool that I wanted, and all Javascript-controlled build. But for some specific-to-my requirements reason that I don't remember anymore I ended writing more customized build-pipeline handler and I run into possibly quite similar problem as the author of issue described: Errors in external process invocations were detected (i.e. return value from command), but their error messages were not caught. The problem was simply, that I had not redirected stderr of Nodejs-started child process to my child process output collector function in my "task handler". Piping both, stdout and std err to output collector fixed the problem.

polarlightning avatar Jul 08 '20 13:07 polarlightning

well i thought this library/module would exactly do that, since it internally starts child processes. Maybe i'm not getting it, but how to pipe stdout & stderr like you said?

michapixel avatar Jul 08 '20 14:07 michapixel

Tasksfile source code in task.js seems to be using NodeJs 'execSync'-function to execute commands. There is one parameter passed that is particularly interesting: "stdio: 'inherit'", which seems to be not enough to pipe stderr to be printed (i.e. your problem as I understood it). In my own implementation I used spawn (async) instread of execSync, which has better documented way of handling stderr and stdout separately. Please try to study NodeJs 'execSync' documentation and also see if you can alter your command itself (i.e. redirect stderr to your stdout, if it fits your case in the command itself ) or try modifying Tasksfile source.

polarlightning avatar Jul 08 '20 14:07 polarlightning