Skip to content

feat(jobs): add Jobs.stop() method [PLT-100574]#337

Open
ninja-shreyash wants to merge 1 commit intomainfrom
feat/sdk-plt-100574
Open

feat(jobs): add Jobs.stop() method [PLT-100574]#337
ninja-shreyash wants to merge 1 commit intomainfrom
feat/sdk-plt-100574

Conversation

@ninja-shreyash
Copy link
Copy Markdown
Contributor

Method Added

Layer Method Signature
Service jobs.stop() stop(jobKeys: string[], folderId: number, options?: JobStopOptions): Promise<OperationResponse<JobStopData>>

Endpoint Called

Method HTTP Endpoint OAuth Scope
stop() (resolve) GET /orchestrator_/odata/Jobs OR.Jobs
stop() (action) POST /orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StopJobs OR.Jobs
  • Extends FolderScopedService — sets X-UIPATH-OrganizationUnitId header
  • Composite method: resolves UUID keys → integer IDs, then calls StopJobs OData action
  • Keys are chunked in batches of 50 to avoid URL length limits
  • Supports SoftStop (graceful) and Kill (forceful) strategies via existing StopStrategy enum

Example Usage

import { UiPath } from '@uipath/uipath-typescript/core';
import { Jobs } from '@uipath/uipath-typescript/jobs';

const sdk = new UiPath(config);
await sdk.initialize();
const jobs = new Jobs(sdk);

// Stop a single job with default soft stop
const result = await jobs.stop(
  ['c80c3b30-f010-4eb8-82d4-b67bc615e137'],
  123
);

// Force-kill multiple jobs
const killResult = await jobs.stop(
  ['c80c3b30-f010-4eb8-82d4-b67bc615e137', '24ef1040-454d-4184-b994-c641ee32318d'],
  123,
  { strategy: StopStrategy.Kill }
);

API Response vs SDK Response

Composition flow

1. GET /odata/Jobs?$filter=Key in ('key1','key2',...)&$select=Id,Key
   → Resolves UUID keys to integer IDs (chunked in batches of 50)
2. POST /odata/Jobs/UiPath.Server.Configuration.OData.StopJobs
   Body: { jobIds: [int,...], strategy: "SoftStop" | "Kill" }
   → Returns empty 200 on success
Final: OperationResponse<JobStopData> = { success: true, data: { jobIds: [int,...] } }

Additional fix

Added responseType: 'text' handling to api-client.ts for endpoints returning empty HTTP 200 bodies (StopJobs returns 200 with no body, not 204).

Files

Area Files
Endpoint src/utils/constants/endpoints/orchestrator.ts
Types src/models/orchestrator/jobs.types.ts
Models src/models/orchestrator/jobs.models.ts
Service src/services/orchestrator/jobs/jobs.ts
Core src/core/http/api-client.ts (text responseType support)
Unit tests tests/unit/services/orchestrator/jobs.test.ts (12 tests)
Integration tests tests/integration/shared/orchestrator/jobs.integration.test.ts (5 tests)
Test utils tests/utils/constants/jobs.ts
Docs docs/oauth-scopes.md

Refs PLT-100574

🤖 Auto-generated using onboarding skills

@ninja-shreyash ninja-shreyash requested a review from a team March 30, 2026 12:24
Add stop method to the Jobs service that stops one or more jobs by their
UUID keys. Resolves keys to integer IDs in batches of 50, then calls the
StopJobs OData action. Supports SoftStop and Kill strategies.

Also adds text responseType handling to api-client for endpoints returning
empty 200 responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown


const missingKeys = uniqueKeys.filter((key) => !keyToIdMap.has(key));
if (missingKeys.length > 0) {
throw new Error(`Jobs not found for keys: ${missingKeys.join(', ')}`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plain Error escapes the typed error hierarchy — callers can't distinguish this from network errors or server failures. Since these are user-supplied keys that don't correspond to any job, ValidationError is the right type (same import already in the file).

Suggested change
throw new Error(`Jobs not found for keys: ${missingKeys.join(', ')}`);
throw new ValidationError({ message: `Jobs not found for keys: ${missingKeys.join(', ')}` });

const response = await this.get<CollectionResponse<{ Key: string; Id: number }>>(
JOB_ENDPOINTS.GET_ALL,
{
params: { $filter: filter, $select: 'Id,Key' },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing $top is a latent bug. Without it the endpoint uses its default page size (typically 20 for Orchestrator OData). A chunk can contain up to 50 keys; if the API pages at 20, the last 30 keys would always be flagged as not found even when they exist.

Suggested change
params: { $filter: filter, $select: 'Id,Key' },
params: { $filter: filter, $select: 'Id,Key', $top: chunk.length },


if (!folderId) {
console.warn('INTEGRATION_TEST_FOLDER_ID not configured, skipping stop test.');
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the integration test rules, console.warn + return is reserved for preconditions outside the test's control (e.g. no running jobs available). Missing folderId is a misconfigured environment — the test simply cannot run. That case should throw so CI doesn't silently pass unconfigured tests.

Suggested change
return;
throw new Error('INTEGRATION_TEST_FOLDER_ID not configured — cannot run stop test.');

* const killResult = await jobs.stop(
* ['c80c3b30-f010-4eb8-82d4-b67bc615e137', '24ef1040-454d-4184-b994-c641ee32318d'],
* 123,
* { strategy: StopStrategy.Kill }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StopStrategy is used in the second example but never imported, so the snippet won't compile as written. Add it to the existing import line shown earlier in the example.

Suggested change
* { strategy: StopStrategy.Kill }
* { strategy: StopStrategy.Kill }

The first @example import line should read:

import { Jobs, StopStrategy } from '@uipath/uipath-typescript/jobs';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant