{"record":{"id":"9135d5a9527440fb","repo":"paascloud/paascloud-master","slug":"outid","errorCode":null,"errorMessage":"outId不能为空","messagePattern":"outId不能为空","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"paascloud-provider/paascloud-provider-opc/src/main/java/com/paascloud/provider/consumer/OptSendSmsTopicConsumer.java","lineNumber":55,"sourceCode":"\t * Handler send sms topic.\n\t *\n\t * @param body      the body\n\t * @param topicName the topic name\n\t * @param tags      the tags\n\t * @param keys      the keys\n\t */\n\tpublic void handlerSendSmsTopic(String body, String topicName, String tags, String keys) {\n\t\tMqMessage.checkMessage(body, keys, topicName);\n\t\tSendSmsRequest sendSmsRequest;\n\t\ttry {\n\t\t\tsendSmsRequest = JacksonUtil.parseJson(body, SendSmsRequest.class);\n\t\t} catch (Exception e) {\n\t\t\tlog.error(\"发送短信MQ出现异常={}\", e.getMessage(), e);\n\t\t\tthrow new IllegalArgumentException(\"JSON转换异常\", e);\n\t\t}\n\t\tString ipAddr = sendSmsRequest.getOutId();\n\t\tif (StringUtils.isEmpty(ipAddr)) {\n\t\t\tthrow new IllegalArgumentException(\"outId不能为空\");\n\t\t}\n\t\tsmsService.sendSms(sendSmsRequest);\n\t}\n}\n","sourceCodeStart":37,"sourceCodeEnd":60,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-provider/paascloud-provider-opc/src/main/java/com/paascloud/provider/consumer/OptSendSmsTopicConsumer.java#L37-L60","documentation":"IllegalArgumentException(\"outId不能为空\") thrown by OptSendSmsTopicConsumer.handlerSendSmsTopic after successful deserialization when SendSmsRequest.outId is empty. outId is required for the Aliyun SMS call (it maps the send request to a business identifier), so the consumer rejects the message before invoking smsService.sendSms.","triggerScenarios":"A message on the SMS topic parses fine but was published without setting outId, or the producer populates a differently named field (so outId deserializes to null), or outId was intentionally blank for templates not requiring it but the consumer always requires it.","commonSituations":"Producer DTO changed to make outId optional; producer code path that builds SendSmsRequest without outId; copy-pasted producer code sending the email payload shape to the SMS topic.","solutions":["Fix the producer to always set outId before publishing to the SMS topic","Check field naming/annotations so outId actually maps during JSON deserialization","If outId is genuinely optional for some templates, guard conditionally instead of rejecting","Republish the failed message with outId set"],"exampleFix":"// before\nSendSmsRequest sendSmsRequest = new SendSmsRequest();\nsendSmsRequest.setPhoneNumber(...);\n// after\nSendSmsRequest sendSmsRequest = new SendSmsRequest();\nsendSmsRequest.setPhoneNumber(...);\nPreconditions.checkArgument(StringUtils.isNotEmpty(outId), \"outId must be set\");\nsendSmsRequest.setOutId(outId);","handlingStrategy":"validation","validationCode":"if (sendSmsRequest == null || StringUtils.isEmpty(sendSmsRequest.getOutId())) {\n    log.warn(\"sms message missing outId, discarding\");\n    return;\n}","typeGuard":"if (sendSmsRequest == null) { return; }\nString outId = sendSmsRequest.getOutId();\nif (outId == null || outId.trim().isEmpty()) { return; }","tryCatchPattern":"try { smsService.sendSms(sendSmsRequest); } catch (IllegalArgumentException e) { log.error(\"invalid sms request: {}\", e.getMessage()); }","preventionTips":["Set outId on the producer before publishing","Validate SendSmsRequest fields at the producer boundary","Keep DTO field mappings consistent (annotations) so outId survives serialization","Add a producer-side unit test asserting outId is populated"],"tags":["mq-consumer","validation","sms","missing-field"],"backgroundTag":"empty-required-field","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}