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
6 changes: 6 additions & 0 deletions .changeset/dirty-ends-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@knime/components": patch
---

FileExplorer: fix types of OnClickOutside ignores
FileExplorer: disable options menu when multiple items are selected
5 changes: 5 additions & 0 deletions .changeset/old-rocks-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@knime/hub-features": patch
---

fix rfcErrors parser and return undefined on error
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,7 @@ useResizeObserver(containerProps.ref, containerProps.onScroll);
contextMenuAnchor?.openedBy === 'optionsMenu' &&
contextMenuAnchor?.item.id === item.id
"
:disabled="selectedItems.length > 1"
compact
@dblclick.stop
@pointerdown.stop
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FetchError, type FetchOptions } from "ofetch";
import { type FetchOptions } from "ofetch";

import { type HubAvatarData, rfcErrors } from "@knime/hub-features";
import { VERSION_DEFAULT_LIMIT } from "@knime/hub-features/versions";
Expand Down Expand Up @@ -37,11 +37,7 @@ export const useVersionsApi = ({

return await $ofetch(path, { ...defaults, ...fetchOptions });
} catch (error) {
if (error instanceof FetchError) {
throw rfcErrors.tryParse(error);
}

throw error;
throw rfcErrors.tryParse(error) ?? error;
}
};

Expand Down
47 changes: 26 additions & 21 deletions packages/hub-features/src/rfcErrors/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { FetchError } from "ofetch";
import { FetchError } from "ofetch";

import { rfcErrors } from "..";
import { RFCError } from "../types";
Expand Down Expand Up @@ -46,16 +46,15 @@ describe("rfcErrors", () => {
response.headers.set("x-request-id", "request-id");
response.headers.set("x-error-id", "error-id");

const fetchError: FetchError = {
data: {
title: "The title",
details: ["detail 1"],
},
statusCode: 400,
response,
name: "",
message: "",
const fetchError = new FetchError("");
fetchError.data = {
title: "The title",
details: ["detail 1"],
};
fetchError.statusCode = 400;
fetchError.response = response;
fetchError.name = "";
fetchError.message = "";

const expectedError = new RFCError({
title: "The title",
Expand All @@ -71,21 +70,27 @@ describe("rfcErrors", () => {
expect(parsedError).toEqual(expectedError);
});

it("should NOT parse into RFCError", () => {
const fetchError: FetchError = {
data: {
title: "The title",
details: ["detail 1"],
},
statusCode: 400,
name: "",
message: "",
it("should NOT parse into RFCError if response is missing", () => {
const fetchError = new FetchError("");
fetchError.data = {
title: "The title",
details: ["detail 1"],
};
fetchError.statusCode = 400;
fetchError.name = "";
fetchError.message = "";

const parsedError = rfcErrors.tryParse(fetchError);

expect(parsedError instanceof rfcErrors.RFCError).toBe(false);
expect(parsedError).toBe(fetchError);
expect(parsedError).toBeUndefined();
});

it("should NOT parse into RFCError if no FetchError is given", () => {
const error = new Error("");

const parsedError = rfcErrors.tryParse(error);

expect(parsedError).toBeUndefined();
});
});
});
19 changes: 13 additions & 6 deletions packages/hub-features/src/rfcErrors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,28 @@ const toToast = ({
};

/**
* Try to parse an ofetch's `FetchError` to an `RFCError`. When parsing is not possible
* it returns the same `FetchError` given unchanged.
* Parse an ofetch's `FetchError` to an `RFCError`.
* When parsing is not possible it returns undefined.
*/
const tryParse = (error: FetchError): RFCError | FetchError => {
const tryParse = (error: unknown): RFCError | undefined => {
if (!(error instanceof FetchError)) {
return undefined;
}

if (!error.response) {
return error;
return undefined;
}

const responseDate = error.response.headers.get("date")
? new Date(error.response.headers.get("date")!)
: undefined;

const title =
typeof error.data === "string" ? error.data : error.data?.title ?? "";

const rfcErrorData: RFCErrorData = {
title: error.data.title as string,
details: error.data.details as string[] | undefined,
title: title as string,
details: error.data?.details as string[] | undefined,
status: error.statusCode as number,
date: responseDate,
requestId: error.response.headers.get("x-request-id") ?? undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,7 @@ export const useDownloadArtifact = (
} catch (error: unknown) {
// here only errors thrown by the initial requests are caught;
// errors occurring while polling will be handled in pollDownloadItem
if (error instanceof FetchError) {
throw rfcErrors.tryParse(error);
}
throw error;
throw rfcErrors.tryParse(error) ?? error;
}
};

Expand Down
6 changes: 1 addition & 5 deletions packages/hub-features/src/useFileUpload/useFileUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,7 @@ export const useFileUpload = (options: UseFileUploadOptions = {}) => {

useUploadManagerResult.start(parentId, uploadPayload);
} catch (error) {
if (error instanceof FetchError) {
throw rfcErrors.tryParse(error);
}

throw error;
throw rfcErrors.tryParse(error) ?? error;
} finally {
// errors can only be thrown in the prepareUpload call, useUploadManagerResult.start does its own error handling
prepareQueueSize.value -= enqueableFiles.length;
Expand Down