Search code examples
javascriptfunctional-programmingfolktale

migrating from data.task to folktale on handling rejection


In data.task package, I could resolve or reject a api call as following:

import Task from 'data.task';
import fs from 'fs';

const readFile = (filename, enc) => {
  return new Task((rej, res) =>
    fs.readFile(filename, enc, (err, contents) => {
      err ? rej(err) : res(contents);
    })
  );
};

How would I accomplish that in the new folktale version of Task? I can resolve requests, but how do I reject? I have tried the following:

const {task, rejected} = require('folktale/concurrency/task');
import fs from 'fs';

const readFile = (filename, enc) => {
  return task(res => {
    fs.readFile(filename, enc, (err, contents) => {
      err ? rejected(err) : res.resolve(contents);
    });
  });
};

const writeFile = (filename, contents) => {
  return task(res => {
    fs.writeFile(filename, contents, (err, success) => {
      err ? rejected(err) : res.resolve(success);
    });
  });
};

const app = readFile('FILE_DOESNOT_EXIST.json', 'utf-8')
  .map(contents => contents.replace(/8/g, '6'))
  .chain(contents => writeFile('config1.json', contents));

app.run().listen({
  onCancelled: () => {
    console.log('the task was cancelled');
  },
  onRejected: () => {
    console.log('something went wrong');
  },
  onResolved: value => {
    console.log(`The value is Good`);
  },
});

When I gave a file that doesn't exist, the onRejected handler does not get called.

What do I expect to see: Since I have the program read a file that does not exist, it should run onRejected which should log something went wrong.

What do I see now: Nothing. The program does not bug out, but it also does not produce anything, it simply runs as normal.

When using data.task(the older version of Task), I can use reject which is why it stills works there. How do I do it now with the new version of Task?


Solution

  • Ok this is really silly! For some reason I could not find this solution right away on the doc.That's why I imported the rejected from task...

    Basically resolver function coming from task has not only resolve, but also reject, which should have been obvious, but it was not on the doc.

    So here is working code:

    import {task} from 'folktale/concurrency/task';
    import fs from 'fs';
    
    const readFile = (filename, enc) => {
      return task(res => {
        fs.readFile(filename, enc, (err, contents) => {
          err ? res.reject() : res.resolve(contents);
        });
      });
    };
    
    const writeFile = (filename, contents) => {
      return task(res => {
        fs.writeFile(filename, contents, (err, success) => {
          err ? res.reject() : res.resolve(success);
        });
      });
    };
    
    const app = readFile('confg.json', 'utf-8')
      .map(contents => contents.replace(/8/g, '6'))
      .chain(contents => writeFile('config1.json', contents));
    
    app.run().listen({
      onCancelled: () => {
        console.log('the task was cancelled');
      },
      onRejected: () => {
        console.log('something went wrong');
      },
      onResolved: value => {
        console.log(`The value is Good`);
      },
    });