{"record":{"id":"14ef03b0bc9536c6","repo":"floci-io/floci","slug":"errortype","errorCode":"{errorType}","errorMessage":"{message}","messagePattern":"\\{message\\}","errorType":"exception","errorClass":"VtlErrorSignal","httpStatus":null,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/appsync/graphql/util/AppSyncUtil.java","lineNumber":209,"sourceCode":"        if (value == null) return \"Null\";\n        if (value instanceof String) return \"String\";\n        if (value instanceof Boolean) return \"Boolean\";\n        if (value instanceof Number) return \"Number\";\n        if (value instanceof List<?>) return \"List\";\n        if (value instanceof Map<?, ?>) return \"Map\";\n        return \"Object\";\n    }\n\n    public String authType() {\n        return authTypeValue;\n    }\n\n    public void error(String message) {\n        throw new VtlErrorSignal(message, \"Unknown\", null, null);\n    }\n\n    public void error(String message, String errorType) {\n        throw new VtlErrorSignal(message, errorType, null, null);\n    }\n\n    public void error(String message, String errorType, Object data) {\n        throw new VtlErrorSignal(message, errorType, data, null);\n    }\n\n    public void error(String message, String errorType, Object data, Object errorInfo) {\n        throw new VtlErrorSignal(message, errorType, data, errorInfo);\n    }\n\n    public void appendError(String message) {\n        appendErrorInternal(message, \"Unknown\", null, null);\n    }\n\n    public void appendError(String message, String errorType) {\n        appendErrorInternal(message, errorType, null, null);\n    }\n","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/appsync/graphql/util/AppSyncUtil.java#L191-L227","documentation":"Implements $util.error(message, errorType) from AppSync VTL: aborts the resolver and reports the message with the caller-supplied errorType (e.g. 'Unauthorized', 'Conflict'). The emulator throws VtlErrorSignal carrying both fields; the GraphQL data-plane turns it into an error entry with errorType metadata.","triggerScenarios":"A mapping template explicitly calls the two-argument form, e.g. $util.error(\"mutation failed\", \"DynamoDB:ConditionalCheckFailedException\"). Common in mutation resolvers that translate downstream failures into typed GraphQL errors.","commonSituations":"Templates copied from AWS docs or blog posts that use typed $util.error for conditional-write failures; clients that switch on errorType and break when the type string doesn't match exactly.","solutions":["Check errors[0].errorType (or extensions) in the GraphQL response to find the originating template call.","If the type is unexpected, fix the condition guarding the $util.error call rather than the message.","Keep errorType strings aligned with AWS conventions (e.g. 'DynamoDB:ConditionalCheckFailedException') so SDK/AppSync tooling recognizes them.","For recoverable cases, use $util.appendError instead so the resolver continues and returns data."],"exampleFix":"## before\n$util.error(\"write failed\", \"RandomError\")\n\n## after\n$util.error(\"write failed\", \"DynamoDB:ConditionalCheckFailedException\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return evaluateTemplate(reqMapping, ctx);\n} catch (VtlErrorSignal e) {\n    if (\"Unauthorized\".equals(e.getErrorType())) throw new UnauthorizedException(e);\n    throw new TypedGraphQLError(e.getMessage(), e.getErrorType(), e);\n}","preventionTips":["Standardize errorType strings against AWS service error names.","Log errorType alongside message so production incidents are searchable by type.","Use $util.appendError when the resolver should continue and still return data."],"tags":["appsync","vtl","resolver","graphql","typed-error"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}