frontend-app-api: refine app error types
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -411,7 +411,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'INVALID_CONFIGURATION',
|
||||
code: 'EXTENSION_CONFIGURATION_INVALID',
|
||||
message:
|
||||
"Invalid configuration for extension 'app/test'; caused by Error: Expected number, received string at 'other'",
|
||||
context: { node },
|
||||
@@ -443,7 +443,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test'; caused by NopeError: NOPE",
|
||||
context: { node },
|
||||
@@ -476,7 +476,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test', duplicate extension data 'test' received via output 'test2'",
|
||||
context: { node },
|
||||
@@ -508,7 +508,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test', unknown output provided via 'nonexistent'",
|
||||
context: { node },
|
||||
@@ -544,7 +544,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test', input 'singleton' is required but was not received",
|
||||
context: { node },
|
||||
@@ -669,7 +669,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test', expected exactly one 'singleton' input but received multiple: 'app/test', 'app/test'",
|
||||
context: { node },
|
||||
@@ -713,7 +713,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test', expected at most one 'singleton' input but received multiple: 'app/test', 'app/test'",
|
||||
context: { node },
|
||||
@@ -751,7 +751,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test', extension 'app/test' could not be attached because its output data ('test', 'other') does not match what the input 'singleton' requires ('other')",
|
||||
context: { node },
|
||||
@@ -1073,7 +1073,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'INVALID_CONFIGURATION',
|
||||
code: 'EXTENSION_CONFIGURATION_INVALID',
|
||||
message:
|
||||
"Invalid configuration for extension 'app/test'; caused by Error: Expected number, received string at 'other'",
|
||||
context: { node },
|
||||
@@ -1121,7 +1121,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FACTORY_INVALID_OUTPUT',
|
||||
code: 'EXTENSION_INVALID',
|
||||
message: 'extension factory did not provide an iterable object',
|
||||
context: { node: expect.anything() },
|
||||
},
|
||||
@@ -1138,8 +1138,8 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
// TODO: This should probably be EXTENSION_FACTORY_INVALID_OUTPUT
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
// TODO: This should probably be EXTENSION_INVALID
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'test', extension factory override did not provide an iterable object",
|
||||
context: { node: expect.anything() },
|
||||
@@ -1157,8 +1157,8 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
// TODO: This should probably be EXTENSION_FACTORY_INVALID_OUTPUT
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
// TODO: This should probably be EXTENSION_INVALID
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'test', extension factory middleware did not provide an iterable object",
|
||||
context: { node: expect.anything() },
|
||||
@@ -1175,7 +1175,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FACTORY_INVALID_OUTPUT',
|
||||
code: 'EXTENSION_INVALID',
|
||||
message: 'extension factory did not provide an iterable object',
|
||||
context: { node: expect.anything() },
|
||||
},
|
||||
@@ -1194,7 +1194,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FACTORY_INVALID_OUTPUT',
|
||||
code: 'EXTENSION_INVALID',
|
||||
message: 'extension factory did not provide an iterable object',
|
||||
context: { node: expect.anything() },
|
||||
},
|
||||
@@ -1214,8 +1214,8 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
// TODO: This should probably be EXTENSION_FACTORY_INVALID_OUTPUT
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
// TODO: This should probably be EXTENSION_INVALID
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'test:test', extension factory did not provide an iterable object",
|
||||
context: { node: expect.anything() },
|
||||
@@ -1236,8 +1236,8 @@ describe('instantiateAppNodeTree', () => {
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
// TODO: This should probably be EXTENSION_FACTORY_INVALID_OUTPUT
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
// TODO: This should probably be EXTENSION_INVALID
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'test:test', original blueprint factory did not provide an iterable object",
|
||||
context: { node: expect.anything() },
|
||||
@@ -1271,7 +1271,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message:
|
||||
"Failed to instantiate extension 'app/test'; caused by NopeError: NOPE",
|
||||
context: { node },
|
||||
@@ -1303,7 +1303,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FACTORY_DUPLICATE_OUTPUT',
|
||||
code: 'EXTENSION_OUTPUT_CONFLICT',
|
||||
message: "extension factory output duplicate data 'test'",
|
||||
context: { dataRefId: 'test', node },
|
||||
},
|
||||
@@ -1335,7 +1335,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FACTORY_MISSING_REQUIRED_OUTPUT',
|
||||
code: 'EXTENSION_OUTPUT_MISSING',
|
||||
message: "missing required extension data output 'test'",
|
||||
context: {
|
||||
dataRefId: 'test',
|
||||
@@ -1370,7 +1370,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeDefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FACTORY_UNEXPECTED_OUTPUT',
|
||||
code: 'EXTENSION_OUTPUT_IGNORED',
|
||||
message: "unexpected output 'test'",
|
||||
context: { dataRefId: 'test', node },
|
||||
},
|
||||
@@ -1404,7 +1404,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_MISSING_REQUIRED_INPUT',
|
||||
code: 'EXTENSION_ATTACHMENT_MISSING',
|
||||
message: "input 'singleton' is required but was not received",
|
||||
context: { inputName: 'singleton', node },
|
||||
},
|
||||
@@ -1529,7 +1529,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_TOO_MANY_ATTACHMENTS',
|
||||
code: 'EXTENSION_ATTACHMENT_CONFLICT',
|
||||
message:
|
||||
"expected exactly one 'singleton' input but received multiple: 'app/test', 'app/test'",
|
||||
context: { inputName: 'singleton', node },
|
||||
@@ -1573,7 +1573,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_TOO_MANY_ATTACHMENTS',
|
||||
code: 'EXTENSION_ATTACHMENT_CONFLICT',
|
||||
message:
|
||||
"expected at most one 'singleton' input but received multiple: 'app/test', 'app/test'",
|
||||
context: { inputName: 'singleton', node },
|
||||
@@ -1610,7 +1610,7 @@ describe('instantiateAppNodeTree', () => {
|
||||
).toBeUndefined();
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_MISSING_INPUT_DATA',
|
||||
code: 'EXTENSION_INPUT_DATA_MISSING',
|
||||
message:
|
||||
"extension 'app/test' could not be attached because its output data ('test') does not match what the input 'singleton' requires ('other')",
|
||||
context: { node, inputName: 'singleton' },
|
||||
|
||||
@@ -102,7 +102,7 @@ function resolveInputDataContainer(
|
||||
mapWithFailures(extensionData, ref => {
|
||||
if (dataMap.has(ref.id)) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_DUPLICATE_INPUT',
|
||||
code: 'EXTENSION_INPUT_DATA_IGNORED',
|
||||
message: `Unexpected duplicate input data '${ref.id}'`,
|
||||
});
|
||||
return;
|
||||
@@ -120,7 +120,7 @@ function resolveInputDataContainer(
|
||||
.join(', ');
|
||||
|
||||
collector.report({
|
||||
code: 'EXTENSION_MISSING_INPUT_DATA',
|
||||
code: 'EXTENSION_INPUT_DATA_MISSING',
|
||||
message: `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,
|
||||
});
|
||||
throw INSTANTIATION_FAILED;
|
||||
@@ -265,7 +265,7 @@ function resolveV2Inputs(
|
||||
if (attachedNodes.length > 1) {
|
||||
const attachedNodeIds = attachedNodes.map(e => e.spec.id).join("', '");
|
||||
collector.report({
|
||||
code: 'EXTENSION_TOO_MANY_ATTACHMENTS',
|
||||
code: 'EXTENSION_ATTACHMENT_CONFLICT',
|
||||
message: `expected ${
|
||||
input.config.optional ? 'at most' : 'exactly'
|
||||
} one '${inputName}' input but received multiple: '${attachedNodeIds}'`,
|
||||
@@ -274,7 +274,7 @@ function resolveV2Inputs(
|
||||
} else if (attachedNodes.length === 0) {
|
||||
if (!input.config.optional) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_MISSING_REQUIRED_INPUT',
|
||||
code: 'EXTENSION_ATTACHMENT_MISSING',
|
||||
message: `input '${inputName}' is required but was not received`,
|
||||
});
|
||||
throw INSTANTIATION_FAILED;
|
||||
@@ -326,7 +326,7 @@ export function createAppNodeInstance(options: {
|
||||
};
|
||||
} catch (e) {
|
||||
collector.report({
|
||||
code: 'INVALID_CONFIGURATION',
|
||||
code: 'EXTENSION_CONFIGURATION_INVALID',
|
||||
message: `Invalid configuration for extension '${id}'; caused by ${e}`,
|
||||
});
|
||||
return undefined;
|
||||
@@ -393,7 +393,7 @@ export function createAppNodeInstance(options: {
|
||||
!outputDataValues?.[Symbol.iterator]
|
||||
) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_FACTORY_INVALID_OUTPUT',
|
||||
code: 'EXTENSION_INVALID',
|
||||
message: 'extension factory did not provide an iterable object',
|
||||
});
|
||||
throw INSTANTIATION_FAILED;
|
||||
@@ -403,7 +403,7 @@ export function createAppNodeInstance(options: {
|
||||
mapWithFailures(outputDataValues, value => {
|
||||
if (outputDataMap.has(value.id)) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_FACTORY_DUPLICATE_OUTPUT',
|
||||
code: 'EXTENSION_OUTPUT_CONFLICT',
|
||||
message: `extension factory output duplicate data '${value.id}'`,
|
||||
context: {
|
||||
dataRefId: value.id,
|
||||
@@ -421,7 +421,7 @@ export function createAppNodeInstance(options: {
|
||||
if (value === undefined) {
|
||||
if (!ref.config.optional) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_FACTORY_MISSING_REQUIRED_OUTPUT',
|
||||
code: 'EXTENSION_OUTPUT_MISSING',
|
||||
message: `missing required extension data output '${ref.id}'`,
|
||||
context: {
|
||||
dataRefId: ref.id,
|
||||
@@ -439,7 +439,7 @@ export function createAppNodeInstance(options: {
|
||||
for (const dataRefId of outputDataMap.keys()) {
|
||||
// TODO: Make this a warning
|
||||
collector.report({
|
||||
code: 'EXTENSION_FACTORY_UNEXPECTED_OUTPUT',
|
||||
code: 'EXTENSION_OUTPUT_IGNORED',
|
||||
message: `unexpected output '${dataRefId}'`,
|
||||
context: {
|
||||
dataRefId: dataRefId,
|
||||
@@ -449,7 +449,7 @@ export function createAppNodeInstance(options: {
|
||||
}
|
||||
} else {
|
||||
collector.report({
|
||||
code: 'UNEXPECTED_EXTENSION_VERSION',
|
||||
code: 'EXTENSION_INVALID',
|
||||
message: `unexpected extension version '${
|
||||
(internalExtension as any).version
|
||||
}'`,
|
||||
@@ -459,7 +459,7 @@ export function createAppNodeInstance(options: {
|
||||
} catch (e) {
|
||||
if (e !== INSTANTIATION_FAILED) {
|
||||
collector.report({
|
||||
code: 'FAILED_TO_INSTANTIATE_EXTENSION',
|
||||
code: 'EXTENSION_FACTORY_ERROR',
|
||||
message: `Failed to instantiate extension '${id}'${
|
||||
e.name === 'Error' ? `, ${e.message}` : `; caused by ${e}`
|
||||
}`,
|
||||
|
||||
@@ -440,7 +440,7 @@ describe('resolveAppNodeSpecs', () => {
|
||||
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FORBIDDEN',
|
||||
code: 'EXTENSION_IGNORED',
|
||||
message:
|
||||
"It is forbidden to override the 'test/forbidden' extension, attempted by the 'test' plugin",
|
||||
context: {
|
||||
@@ -473,7 +473,7 @@ describe('resolveAppNodeSpecs', () => {
|
||||
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_FORBIDDEN',
|
||||
code: 'EXTENSION_IGNORED',
|
||||
message:
|
||||
"It is forbidden to override the 'forbidden' extension, attempted by the 'forbidden' plugin",
|
||||
context: {
|
||||
@@ -496,7 +496,7 @@ describe('resolveAppNodeSpecs', () => {
|
||||
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'EXTENSION_CONFIG_FORBIDDEN',
|
||||
code: 'INVALID_EXTENSION_CONFIG_KEY',
|
||||
message: "Configuration of the 'forbidden' extension is forbidden",
|
||||
context: {
|
||||
extensionId: 'forbidden',
|
||||
|
||||
@@ -56,7 +56,7 @@ export function resolveAppNodeSpecs(options: {
|
||||
) => {
|
||||
if (forbidden.has(extension.id)) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_FORBIDDEN',
|
||||
code: 'EXTENSION_IGNORED',
|
||||
message: `It is forbidden to override the '${extension.id}' extension, attempted by the '${extension.plugin.id}' plugin`,
|
||||
context: {
|
||||
plugin: extension.plugin,
|
||||
@@ -153,13 +153,13 @@ export function resolveAppNodeSpecs(options: {
|
||||
}
|
||||
}
|
||||
|
||||
const seendExtensionIds = new Set<string>();
|
||||
const seenExtensionIds = new Set<string>();
|
||||
const deduplicatedExtensions = configuredExtensions.filter(
|
||||
({ extension, params }) => {
|
||||
if (seendExtensionIds.has(extension.id)) {
|
||||
if (seenExtensionIds.has(extension.id)) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_DUPLICATED',
|
||||
message: `The extension '${extension.id}' is duplicated`,
|
||||
code: 'EXTENSION_IGNORED',
|
||||
message: `The '${extension.id}' extension from the '${params.plugin.id}' plugin is a duplicate and will be ignored`,
|
||||
context: {
|
||||
plugin: params.plugin,
|
||||
extensionId: extension.id,
|
||||
@@ -167,7 +167,7 @@ export function resolveAppNodeSpecs(options: {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
seendExtensionIds.add(extension.id);
|
||||
seenExtensionIds.add(extension.id);
|
||||
return true;
|
||||
},
|
||||
);
|
||||
@@ -178,7 +178,7 @@ export function resolveAppNodeSpecs(options: {
|
||||
|
||||
if (forbidden.has(extensionId)) {
|
||||
collector.report({
|
||||
code: 'EXTENSION_CONFIG_FORBIDDEN',
|
||||
code: 'INVALID_EXTENSION_CONFIG_KEY',
|
||||
message: `Configuration of the '${extensionId}' extension is forbidden`,
|
||||
context: {
|
||||
extensionId,
|
||||
@@ -206,7 +206,7 @@ export function resolveAppNodeSpecs(options: {
|
||||
order.set(extensionId, existing);
|
||||
} else {
|
||||
collector.report({
|
||||
code: 'EXTENSION_CONFIG_UNKNOWN_EXTENSION',
|
||||
code: 'INVALID_EXTENSION_CONFIG_KEY',
|
||||
message: `Extension ${extensionId} does not exist`,
|
||||
context: {
|
||||
extensionId,
|
||||
|
||||
@@ -238,7 +238,7 @@ describe('buildAppTree', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('emits an error when duplicated extensions are detected', () => {
|
||||
it('ignores duplicate extensions', () => {
|
||||
const tree = resolveAppTree(
|
||||
'a',
|
||||
[
|
||||
@@ -248,13 +248,6 @@ describe('buildAppTree', () => {
|
||||
collector,
|
||||
);
|
||||
expect(Array.from(tree.nodes.keys())).toEqual(['a']);
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'DUPLICATE_EXTENSION_ID',
|
||||
message: "Unexpected duplicate extension id 'a'",
|
||||
context: { spec: { ...baseSpec, id: 'a' } },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe('redirects', () => {
|
||||
@@ -300,11 +293,13 @@ describe('buildAppTree', () => {
|
||||
|
||||
expect(collector.collectErrors()).toEqual([
|
||||
{
|
||||
code: 'DUPLICATE_REDIRECT_TARGET',
|
||||
code: 'EXTENSION_INPUT_REDIRECT_CONFLICT',
|
||||
message:
|
||||
"Duplicate redirect target for input 'test' in extension 'b'",
|
||||
context: {
|
||||
spec: { ...baseSpec, id: 'b', extension: e2 },
|
||||
node: expect.objectContaining({
|
||||
spec: { ...baseSpec, id: 'b', extension: e2 },
|
||||
}),
|
||||
inputName: 'test',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -122,15 +122,8 @@ export function resolveAppTree(
|
||||
const redirectTargetsByKey = new Map<string, { id: string; input: string }>();
|
||||
|
||||
for (const spec of specs) {
|
||||
// The main check with a more helpful error message happens in resolveAppNodeSpecs
|
||||
// The main check with a helpful error message happens in resolveAppNodeSpecs
|
||||
if (nodes.has(spec.id)) {
|
||||
errorCollector.report({
|
||||
code: 'DUPLICATE_EXTENSION_ID',
|
||||
message: `Unexpected duplicate extension id '${spec.id}'`,
|
||||
context: {
|
||||
spec,
|
||||
},
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -144,10 +137,10 @@ export function resolveAppTree(
|
||||
const key = makeRedirectKey(replace);
|
||||
if (redirectTargetsByKey.has(key)) {
|
||||
errorCollector.report({
|
||||
code: 'DUPLICATE_REDIRECT_TARGET',
|
||||
code: 'EXTENSION_INPUT_REDIRECT_CONFLICT',
|
||||
message: `Duplicate redirect target for input '${inputName}' in extension '${spec.id}'`,
|
||||
context: {
|
||||
spec,
|
||||
node,
|
||||
inputName,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -14,41 +14,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
AppNode,
|
||||
AppNodeSpec,
|
||||
FrontendPlugin,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { AppNode, FrontendPlugin } from '@backstage/frontend-plugin-api';
|
||||
import { Expand } from '@backstage/types';
|
||||
|
||||
type AppErrorTypes = {
|
||||
// resolveAppNodeSpecs
|
||||
EXTENSION_FORBIDDEN: 'plugin' | 'extensionId';
|
||||
EXTENSION_DUPLICATED: 'plugin' | 'extensionId';
|
||||
EXTENSION_CONFIG_FORBIDDEN: 'extensionId';
|
||||
EXTENSION_CONFIG_UNKNOWN_EXTENSION: 'extensionId';
|
||||
EXTENSION_IGNORED: 'plugin' | 'extensionId';
|
||||
INVALID_EXTENSION_CONFIG_KEY: 'extensionId';
|
||||
// resolveAppTree
|
||||
DUPLICATE_EXTENSION_ID: 'spec';
|
||||
DUPLICATE_REDIRECT_TARGET: 'spec' | 'inputName';
|
||||
EXTENSION_INPUT_REDIRECT_CONFLICT: 'node' | 'inputName';
|
||||
// instantiateAppNodeTree
|
||||
EXTENSION_DUPLICATE_INPUT: 'node' | 'inputName';
|
||||
EXTENSION_MISSING_INPUT_DATA: 'node' | 'inputName';
|
||||
EXTENSION_TOO_MANY_ATTACHMENTS: 'node' | 'inputName';
|
||||
EXTENSION_MISSING_REQUIRED_INPUT: 'node' | 'inputName';
|
||||
INVALID_CONFIGURATION: 'node';
|
||||
EXTENSION_FACTORY_INVALID_OUTPUT: 'node';
|
||||
EXTENSION_FACTORY_DUPLICATE_OUTPUT: 'node' | 'dataRefId';
|
||||
EXTENSION_FACTORY_MISSING_REQUIRED_OUTPUT: 'node' | 'dataRefId';
|
||||
EXTENSION_FACTORY_UNEXPECTED_OUTPUT: 'node' | 'dataRefId';
|
||||
UNEXPECTED_EXTENSION_VERSION: 'node';
|
||||
FAILED_TO_INSTANTIATE_EXTENSION: 'node';
|
||||
EXTENSION_INPUT_DATA_IGNORED: 'node' | 'inputName';
|
||||
EXTENSION_INPUT_DATA_MISSING: 'node' | 'inputName';
|
||||
EXTENSION_ATTACHMENT_CONFLICT: 'node' | 'inputName';
|
||||
EXTENSION_ATTACHMENT_MISSING: 'node' | 'inputName';
|
||||
EXTENSION_CONFIGURATION_INVALID: 'node';
|
||||
EXTENSION_INVALID: 'node';
|
||||
EXTENSION_OUTPUT_CONFLICT: 'node' | 'dataRefId';
|
||||
EXTENSION_OUTPUT_MISSING: 'node' | 'dataRefId';
|
||||
EXTENSION_OUTPUT_IGNORED: 'node' | 'dataRefId';
|
||||
EXTENSION_FACTORY_ERROR: 'node';
|
||||
// createSpecializedApp
|
||||
NO_API_FACTORY: 'node';
|
||||
API_EXTENSION_INVALID: 'node';
|
||||
};
|
||||
|
||||
type AppErrorContext = {
|
||||
node?: AppNode;
|
||||
spec?: AppNodeSpec;
|
||||
plugin?: FrontendPlugin;
|
||||
extensionId?: string;
|
||||
dataRefId?: string;
|
||||
|
||||
@@ -394,7 +394,7 @@ function createApiFactories(options: {
|
||||
factories.push(apiFactory);
|
||||
} else {
|
||||
options.collector.report({
|
||||
code: 'NO_API_FACTORY',
|
||||
code: 'API_EXTENSION_INVALID',
|
||||
message: `API extension '${apiNode.spec.id}' did not output an API factory`,
|
||||
context: {
|
||||
node: apiNode,
|
||||
|
||||
Reference in New Issue
Block a user