Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions apps/sim/connectors/sharepoint/sharepoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,39 @@ describe('resolveFolderTarget', () => {
)
})

it('blames the matched library, not the default one, when its remainder is wrong', async () => {
mockGraph({
...defaultDriveRoute,
...sitesDrivesRoute,
...rootChildren(DEFAULT_DRIVE_ID, [folder('d1', 'Archive')]),
...rootChildren(POLICIES_DRIVE_ID, [folder('p1', 'Onboarding')]),
})

const error = await resolve('Policies/HR').catch((e: Error) => e)

expect(error).toBeInstanceOf(Error)
const message = (error as Error).message
expect(message).toContain('document library "Policies"')
expect(message).toContain('"HR"')
expect(message).toContain('"Onboarding"')
expect(message).not.toContain('document library "Documents"')
expect(message).not.toContain('Shared Documents" should be omitted')
})

it('still offers the prefix hint when the path names the default library itself', async () => {
mockGraph({
...defaultDriveRoute,
...sitesDrivesRoute,
...rootChildren(DEFAULT_DRIVE_ID, [folder('d1', 'Archive')]),
})

const error = await resolve('Shared Documents/Reports').catch((e: Error) => e)

const message = (error as Error).message
expect(message).toContain('document library "Documents"')
expect(message).toContain('Shared Documents" should be omitted')
})

it('surfaces a failure to open the default library rather than reporting not-found', async () => {
mockGraph({
[`${GRAPH}/sites/${SITE_ID}/drive?$select=id,name,webUrl`]: { status: 403 },
Expand Down
29 changes: 24 additions & 5 deletions apps/sim/connectors/sharepoint/sharepoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,25 @@ export async function resolveFolderTarget(
return { driveId: defaultDrive.id, driveName: defaultDriveName, folderId: walked.id }
}

/**
* When the first segment named a real library, that library is the one the
* user meant — report against it and its remainder, not against the default
* library and the full path, which would blame the wrong library and advise
* stripping a prefix that was correct.
*/
const reportDrive = libraryMatch
? { id: libraryMatch.id, name: libraryMatch.name || segments[0] }
: { id: defaultDrive.id, name: defaultDriveName }

throw new Error(
await buildFolderNotFoundMessage(
accessToken,
{ id: defaultDrive.id, name: defaultDriveName },
reportDrive,
siteName || siteUrl,
trimmed,
segments,
libraryMatch ? segments.slice(1) : segments,
drives,
reportDrive.id === defaultDrive.id,
retryOptions
)
)
Expand Down Expand Up @@ -572,6 +583,11 @@ function matchesDriveName(drive: Drive, segment: string): boolean {
/**
* Builds a diagnostic failure message naming the site, the library searched,
* the path attempted, and the folders that actually exist at that level.
*
* `searchedDefaultLibrary` gates the advice about stripping a leading library
* name: that hint only applies when the path was interpreted against the site's
* default library, and would be actively misleading when the caller supplied a
* library name that matched.
*/
async function buildFolderNotFoundMessage(
accessToken: string,
Expand All @@ -580,6 +596,7 @@ async function buildFolderNotFoundMessage(
rawFolderPath: string,
segments: string[],
drives: Drive[],
searchedDefaultLibrary: boolean,
retryOptions?: RetryOptions
): Promise<string> {
const parts = [
Expand Down Expand Up @@ -614,9 +631,11 @@ async function buildFolderNotFoundMessage(
}
}

parts.push(
'The folder path is relative to the document library root, so a leading "Documents" or "Shared Documents" should be omitted unless a folder by that name really exists.'
)
if (searchedDefaultLibrary) {
parts.push(
'The folder path is relative to the document library root, so a leading "Documents" or "Shared Documents" should be omitted unless a folder by that name really exists.'
)
}

return parts.join(' ')
}
Expand Down
Loading