The Job Handler plugin is designed to streamline the handling of Flatfile Jobs. A Job is a large unit of work performed asynchronously, such as processing a file or configuring a Space. This plugin listens for the job:ready event and executes a custom handler function when a matching job is triggered.

Its main purpose is to provide a structured way to manage the lifecycle of a job. It automatically acknowledges the job upon receipt, provides a tick function to report progress back to the user, and handles the final completion or failure status. This is useful for any long-running process initiated within Flatfile, allowing developers to focus on the business logic of the task while the plugin manages the communication with the Flatfile API.

Installation

Install the plugin using npm:

npm install @flatfile/plugin-job-handler

Configuration & Parameters

job

  • Type: string | EventFilter
  • Required: Yes
  • Description: A filter to specify which job the listener should handle. This is typically a string in the format “domain:operation”, for example, “space:configure” or “workbook:submit”.

handler

  • Type: Function
  • Required: Yes
  • Description: An async callback function that contains the logic to be executed for the job. It receives the event object and a tick function as arguments. Throwing an error within this function will cause the job to fail. If it completes successfully, it can optionally return a JobCompleteDetails object to customize the outcome message.

Function signature:

(event: FlatfileEvent, tick: TickFunction) => Promise<void | Flatfile.JobCompleteDetails>

opts.debug

  • Type: boolean
  • Default: false
  • Description: An optional parameter to enable detailed logging for the plugin in the console, which is useful for troubleshooting.

Default Behavior

By default, the plugin listens for the specified job:ready event. When triggered, it immediately acknowledges the job with the Flatfile API, setting its status to “Accepted” and progress to 0%. It then executes the user-provided handler. If the handler completes without returning a value, the plugin marks the job as complete with a default message “Job complete”. If the handler throws an error, the plugin catches it and marks the job as failed, using the error message as the reason.

Usage Examples

Basic Usage

import { FlatfileListener } from '@flatfile/listener';
import { jobHandler } from '@flatfile/plugin-job-handler';

const listener = new FlatfileListener();

listener.use(
  jobHandler('space:configure', async (event, tick) => {
    // Acknowledge the job has started
    await tick(10, 'Starting configuration...');

    // ... your custom logic to configure the space ...
    console.log('Configuring space:', event.context.spaceId);

    // Update progress
    await tick(50, 'Halfway there!');

    // ... more logic ...

    // Job is finished
    await tick(100, 'Configuration complete.');
  })
);

Configuration with Debug

import { FlatfileListener } from '@flatfile/listener';
import { jobHandler } from '@flatfile/plugin-job-handler';

const listener = new FlatfileListener();

// Using the 'opts' parameter to enable debug logging
listener.use(
  jobHandler(
    'workbook:submit',
    async (event) => {
      console.log('Processing submitted workbook...');
      // ... processing logic ...
    },
    { debug: true }
  )
);

Advanced Usage with Custom Outcomes

import { FlatfileListener } from '@flatfile/listener';
import { jobHandler } from '@flatfile/plugin-job-handler';

const listener = new FlatfileListener();

listener.use(
  jobHandler('file:process', async (event, tick) => {
    try {
      await tick(25, 'Processing file...');
      // ... your processing logic ...

      // Return a custom outcome on success
      return {
        outcome: {
          message: 'File processed successfully. 10 new records created.',
          acknowledge: true,
        },
      };
    } catch (error) {
      console.error('An error occurred:', error);
      // Throwing the error will automatically fail the job
      throw new Error('Failed to process the file.');
    }
  })
);

Error Handling Example

import { FlatfileListener } from '@flatfile/listener';
import { jobHandler } from '@flatfile/plugin-job-handler';

const listener = new FlatfileListener();

listener.use(
  jobHandler('data:validate', async (event, tick) => {
    await tick(1, 'Starting validation...');
    const records = await getRecords(event); // Fictional function

    if (records.length === 0) {
      // This will be caught by the plugin and fail the job
      throw new Error('Validation failed: No records found to validate.');
    }

    // ... continue validation ...
  })
);

Troubleshooting

The main tool for troubleshooting is the debug option. Setting opts.debug = true when calling jobHandler will enable verbose logging from the plugin, showing when a job is received and when it is completed. Fatal errors are logged using console.error, which can be monitored in your server logs.

Notes

Requirements and Considerations

This plugin is designed to be used within a Flatfile listener environment, such as a Node.js server running the @flatfile/listener package. It relies on the Flatfile API to update job statuses, so proper API keys and permissions are required for the environment where the listener is running.

Error Handling Patterns

The primary error handling pattern is to wrap the logic inside the handler function in a try...catch block if you need to perform cleanup actions, or to simply throw an error to immediately fail the job. The plugin automatically handles the API call to api.jobs.fail() when an unhandled exception is thrown from the handler.

Function Signatures

function jobHandler(
  job: string | { job: string },
  handler: (event: FlatfileEvent, tick: TickFunction) => Promise<void | Flatfile.JobCompleteDetails>,
  opts?: { debug?: boolean }
): (listener: FlatfileListener) => void

type TickFunction = (progress: number, info?: string) => Promise<Flatfile.JobResponse>

Return Values

  • The jobHandler function returns a plugin function to be passed to listener.use()
  • The handler function can return either void or a Flatfile.JobCompleteDetails object
  • If void is returned, the job is completed with a default success message
  • If a JobCompleteDetails object is returned, it is used to set a custom outcome for the completed job
  • The tick function returns a Promise<Flatfile.JobResponse> which can be awaited but is not required