Skip to content

Latest commit

 

History

History
119 lines (86 loc) · 4.14 KB

MIGRATING_V2-V3.md

File metadata and controls

119 lines (86 loc) · 4.14 KB

Migrating jsforce from v2 to v3

Drop support for old node and browsers

jsforce v3 only supports node >= 18 and modern browsers (see our browserlist config for more info: https://browsersl.ist/#q=last+2+versions%2C+not+dead%2C+%3E+0.2%25).

Node-specific build

The jsforce package is intended to work on browsers and node, as such it needs to include multiple builds which increas its final size. If your project runs on node you can use @jsforce/jsforce-node to reduce your bundle size, see JSFORCE-NODE.md for more info.

Removed deprecated JwtOAuth2 class

This class was added in jsforce v2 to support the JWT Oauth flow, then deprecated in favor of allowing specifying the grant_type in Connection.authorize and the OAuth module. For more info: jsforce#1331 jsforce#1332

Retry on network errors

All HTTP requests are now retried on network errors like ECONNRESET, ECONNREFUSED, ETIMEDOUT, etc. If you had a wrapper around jsforce to retry on these you can remove them.

Error handling

When the Salesforce REST API returns multiple errors, a MULTIPLE_API_ERRORS error will be thrown. Full error details can be accessed in the error.data property.

jsforce < v3 used to pick the first error only and ignore others.

Example: inserting an Account record fails because of two validation rules errors

try {
  await conn.sobject('Account').insert({
    Name: 'ACME',
    Phone: '123',
  })
} catch(error) {
  if (error.errorCode === 'MULTIPLE_API_ERRORS') {
    console.log(error.data)
  }
}
[
  {
    message: "no 'ACME' accounts",
    errorCode: 'FIELD_CUSTOM_VALIDATION_EXCEPTION',
    fields: []
  },
  {
    message: "no '123' phone",
    errorCode: 'FIELD_CUSTOM_VALIDATION_EXCEPTION',
    fields: []
  }
]

Bulk API

Bulk.query returns a promise that resolves to a record stream instead (instead of just returning the stream).

Batch.poll emits inProgress event instead of progress when checking the its status. Payload stays the same.

Batch.poll emits error event and throws if batch state = Failed. In v1 it only emitted the error event which made it easy to miss the server error message unless you subscribed to that event.

Bulk V2 API

Code was moved to its own bulk2 file, if you were importing it like this:

import { IngestJobV2 } from 'jsforce/lib/api/bulk.js';

you should change it to:

import { IngestJobV2 } from 'jsforce/lib/api/bulk2.js';

QueryJobV2.poll and IngestJobV2.poll emit error event and throws if job state = Failed. In v2 it only emitted the error event which made it easy to miss the server error message unless you subscribed to that event.

Bulk2.job now allows to get an existing query or ingest job by ID by specifing the type of job (query or ingest) as the first arg.

Before:

const ingestJob = bulk2.job({ id: jobId });

After:

const queryJob = bulk2.job('query', { id: jobId });

const ingestJob = bulk2.job('ingest', { id: jobId });

Bulk V2 query - streaming API

The following changes were made to the Bulk V2 query module to solve memory-related issues when working with a big amount of records, specifically when paginating over results and having to keep them in memory. The Bulk (V1) module was already doing this so it should also help if you want migrate to Bulk V2 API.

  • Bulk2.query returns a promise that resolves to a record stream instead of the array of records.

Here's an example of how to use a record stream to collect all records by listening to the record event:

let records = [];
const recordStream = await conn.bulk2.query(`SELECT Id, Name FROM Account`)

recordStream
  .on('record', (data) => {
    records = records.concat(data);
  })

console.log(records)
  • QueryJob.getResults method was removed in favor of QueryJob.result. This method would fetch records from the query job and return them, causing your program to run out of memory very quickly on millon of records. QueryJob.result returns a record stream which allows to stream records to any source, see the example above.