# Business Logic — FUW01403SFLogic.handleMskmException() [101 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.FUW01403SF.FUW01403SFLogic` |
| Layer | Frontend Controller / View Logic (package `eo.web.webview.*`) |
| Module | `FUW01403SF` (Package: `eo.web.webview.FUW01403SF`) |

## 1. Role

### FUW01403SFLogic.handleMskmException()

This method is the **unified exception handler for business exceptions** thrown during the second-number service application (2号サービスお申し込み) workflow. It receives a `JCCWebServiceException` (the exception wrapper produced by the downstream web service layer) along with a `funcCode` that indicates the current screen operation mode, and interprets the structured error metadata embedded within the exception to decide how to respond.

The method implements a **routing/dispatch pattern** based on the `status` field of the exception's inner message info. It classifies errors into three categories: **single-item validation errors** (status 1000), **internal or conceptual schema-related check errors** (status 1100/1400), and **external schema correlation errors** (status 1300). For specific, known error conditions — particularly phone number registration conflicts, number portability verification failures, and timestamp concurrency conflicts — the method provides user-friendly, field-level error messages and allows the user to correct their input. For all other unrecognized errors, it re-raises a translated `JCCBusinessException` with a system-level error code so the calling screen can display a generic error.

Its role in the larger system is as a **guard and translator** between the low-level web service exception format and the presentation-layer error display contract. It is called exclusively from `executeCfmMskmService()`, which invokes the MSKM (Multi-Service Keyword Management) service during the application submission phase. This ensures that the user never sees raw service-layer error codes — instead, they see localized messages such as "phone number already exists" or "this record has been modified by another user."

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["handleMskmException se funcCode"])
    START --> LOG["Log Start handleMskmException"]
    LOG --> EXTRACT["Extract moreInfo from se.getMessageList"]
    EXTRACT --> INFO["Get info = moreInfo[0]"]
    INFO --> FIELDS["Extract templateid itemid status errFlg from info"]
    FIELDS --> REPLACETXT["Get replaceTxt from JFUWebCommon.getDispText"]

    FIELDS --> S1000{status == 1000 SINGLEDATA_ERR Single item check error}

    S1000 -->|Yes| CHECK1{templateid ETU0101B010 errFlg E3 itemid key_telno}
    CHECK1 -->|Yes| SETTELNO1["setMessageInfo MSGID_TELNO_ERR - Prompt user to verify phone number"]
    SETTELNO1 --> RET1["Return handled"]
    CHECK1 -->|No| THROW_SE["Throw se delegate to common error handling"]
    S1000 -->|No| S1100_1400{status == 1100 RELATION_ERR OR status == 1400 ENTITY_RELATION_ERR}

    S1100_1400 -->|Yes| CHECK2{templateid EZM0121D010 errFlg EA itemid telno}
    CHECK2 -->|Yes| CHECKFUNC2{funcCode == 2 Check-only}
    CHECKFUNC2 -->|Yes| SETTELNO2["setMessageInfo MSGID_TELNO_ERR - Prompt user to verify phone number"]
    CHECKFUNC2 -->|No| THROW0204_1["Throw JCCBusinessException 0204 Update not allowed"]
    SETTELNO2 --> RET2["Return handled"]
    CHECK2 -->|No| CHECK3{templateid ETU0071A010 itemid key_judge_kyoku_no errFlg EA}
    CHECK3 -->|Yes| CHECKFUNC3{funcCode == 2 Check-only}
    CHECKFUNC3 -->|Yes| SETTELNO3["setMessageInfo MSGID_TELNO_ERR - Prompt user to verify"]
    CHECKFUNC3 -->|No| THROW0204_2["Throw JCCBusinessException 0204 Update not allowed"]
    SETTELNO3 --> RET3["Return handled"]
    CHECK3 -->|No| CHECK4{errFlg EA AND itemid upd_dtm_bf}
    CHECK4 -->|Yes| LOG4["Log Service IF error conflict error"]
    LOG4 --> THROW0204_3["Throw JCCBusinessException 0204 Update not allowed timestamp"]
    S1100_1400 -->|No| S1300{status == 1300 TEMPLATE_CORRELATION_ERR}

    S1300 -->|Yes| CHECK5{itemid ido_div}
    CHECK5 -->|Yes| LOG5["Log Service IF error migration division error"]
    LOG5 --> THROW0102["Throw JCCBusinessException 0102 Contract state error"]
    S1300 -->|No| FINAL["Log Service IF error system error"]
    FINAL --> THROW0002["Throw JCCBusinessException 0002 System error"]
    THROW_SE --> END1(["End exception propagated"])
    THROW0204_1 --> END2(["End exception propagated"])
    THROW0204_2 --> END3(["End exception propagated"])
    THROW0204_3 --> END4(["End exception propagated"])
    THROW0102 --> END5(["End exception propagated"])
    THROW0002 --> END6(["End exception propagated"])
```

**Branch Summary:**

| Branch | Condition (status value) | Meaning |
|--------|--------------------------|---------|
| Branch 1 | `status == 1000` (`SINGLEDATA_ERR`) | Single-item validation error — the field-level check failed |
| Branch 2 | `status == 1100` (`RELATION_ERR`) | Internal schema related check error — entity field consistency check failed |
| Branch 3 | `status == 1400` (`ENTITY_RELATION_ERR`) | Concept schema related check error — higher-level entity relation check failed |
| Branch 4 | `status == 1300` (`TEMPLATE_CORRELATION_ERR`) | External schema correlation check error — cross-entity/template consistency failed |
| Default | No match | Unknown error — treated as a system-level error |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `se` | `final JCCWebServiceException` | The exception thrown by the downstream web service during application processing. It contains structured error metadata (template ID, item ID, status code, error flag) accessible via `getMessageList().getMessageMoreInfoList()`. The first entry in the list (index 0) is used — single-item check errors always produce exactly one entry. |
| 2 | `funcCode` | `String` | The current function code indicating the screen operation mode. `"2"` means check-only mode (confirmed by pressing the Check button, 確認ボタン押下時). This controls whether certain errors are displayed as field-level user prompts (check mode) or thrown as business exceptions that propagate to the screen (submission mode). |

**Instance fields read by this method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `this` (implicit) | `FUW01403SFLogic` | Passed to `JFUWebCommon.setMessageInfo()` as the logic instance for screen message binding |

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JFUWebCommon.getDispText` | - | - | Calls `getDispText` to retrieve the replacement display text for the phone number error message (key: `REP_EKF1900-KW`) |
| - | `JFUWebCommon.setMessageInfo` | - | - | Sets a field-level error message on the screen for the `telno` (phone number) field using message ID `EKF1900-KW` |
| - | `DEBUG_LOG.info` | - | - | Writes log entries for each error path: "Service IF execution error" with sub-descriptions (single item, conflict, migration division, system) |

**How to classify:**
- **R** (Read): `getDispText` reads a replacement text string from a properties file.
- **-** (Output/Display): `setMessageInfo` is a presentation-layer call — it registers an error message on the view model, not a data operation.
- **-** (Logging): `DEBUG_LOG.info` writes to the application log.

This method performs **no CRUD operations** on database entities. It is purely an exception interpretation and error-routing layer. All data modifications, if any, occurred in the caller's service invocation before this method was reached.

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

Screen-level entry point: `executeCfmMskmService()` within `FUW01403SFLogic` directly calls this method.
Terminal operations from this method: `setMessageInfo` [-], `DEBUG_LOG.info` [-]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen: FUW01403SF (Logic) | `FUW01403SFLogic.executeCfmMskmService()` -> `FUW01403SFLogic.handleMskmException` | `setMessageInfo [-]` (screen message set), `DEBUG_LOG.info [-]` (log output) |

**Call chain context:**
`executeCfmMskmService()` is the "confirm MSKM service" method within the same logic class. It invokes the multi-service keyword management web service to process application data. If the service throws a `JCCWebServiceException`, `executeCfmMskmService()` catches it and delegates to `handleMskmException()` for error interpretation and user-friendly message routing.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET / EXEC] (L2298-L2306)

> Initialize: log start, extract error metadata from the exception, and prepare display text.

| # | Type | Code |
|---|------|------|
| 1 | LOG | `DEBUG_LOG.info("----- FUW01403 Start handleMskmException -----")` // Log entry point |
| 2 | EXEC | `X31CMessageMoreInfo[] moreInfo = se.getMessageList().getMessageMoreInfoList()` // Extract error detail array from the web service exception |
| 3 | SET | `X31CMessageMoreInfo info = moreInfo[0]` // Take first entry (single-item check errors always have exactly one entry) |
| 4 | SET | `String templateid = info.getTemplateId()` // Error template ID identifying which screen/error definition generated this exception |
| 5 | SET | `String itemid = info.getItemId()` // Error item ID identifying which field triggered the error |
| 6 | SET | `String status = info.getStatus()` // Error status code (1000/1100/1300/1400) controlling branch routing |
| 7 | SET | `String errFlg = info.getItemCheckErr()` // Error flag (e.g., "E3" = digit error, "EA" = entity-attribute relation check error) |
| 8 | SET | `String replaceTxt = JFUWebCommon.getDispText(JFUScreenConst.SCREEN_ID_FUW01403, DISPTEXT_TELNO_ERR)` // Get replacement text from message properties (key: `REP_EKF1900-KW`) |

**Block 2** — [IF] `status == 1000` (`JPCModelConstant.SINGLEDATA_ERR`, Single item check error) (L2308)

> Handles single-item validation errors. If the error matches the specific phone number format pattern, display a user-friendly prompt. Otherwise, re-throw the original exception for common handling.

| # | Type | Code |
|---|------|------|
| 1 | IF | `status == 1000` `[JPCModelConstant.SINGLEDATA_ERR = "1000"]` // Single item check error |

**Block 2.1** — [IF] (nested in Block 2) `templateid == "ETU0101B010" AND errFlg == "E3" AND itemid == "key_telno"` (L2310)

> Specific phone number digit-format error. The error template is for "same-item check error" (単項目チェックエラー) using template ETU0101B010 (同番移転チェック用届別NTT収容局一覧照会), the error flag is `E3` (`KETA_ERR` = digit error), and the item is `key_telno` (KEY 電話番号). Display a field-level error message and return early.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[TEMPLATEID_ETU0101B010 = "ETU0101B010"] AND [JFUStrConst.KETA_ERR = "E3"] AND [ITEMID_KEY_TELNO = "key_telno"]` |
| 2 | EXEC | `JFUWebCommon.setMessageInfo(this, MSGID_TELNO_ERR, new String[]{replaceTxt}, ITEMID_TELNO)` // Set field-level error message for phone number. Message ID: `EKF1900-KW`, Item ID: `telno`, replacement text: `replaceTxt` |
| 3 | RETURN | `return` // Handled — do not propagate further |

**Block 2.2** — [ELSE] (implicit in Block 2, L2317)

> Any other single-item check error that does not match the specific phone number pattern. Delegate to common error handling by re-throwing the original exception.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw se` // Re-throw original exception — not a special case, delegate to common error handling |

**Block 3** — [IF] `status == 1100` (`RELATION_ERR`) OR `status == 1400` (`ENTITY_RELATION_ERR`) (L2321)

> Handles internal and conceptual schema-related check errors. Three specific sub-cases are handled:
> 1. Phone number duplication (template `EZM0121D010`, the phone number registration SC).
> 2. Number portability verification area agreement error (template `ETU0071A010`).
> 3. Timestamp conflict (optimistic lock / update time mismatch).

| # | Type | Code |
|---|------|------|
| 1 | IF | `[status == 1100 JPCModelConstant.RELATION_ERR] OR [status == 1400 JPCModelConstant.ENTITY_RELATION_ERR]` // Internal/concept schema check error |

**Block 3.1** — [IF] `templateid == "EZM0121D010" AND errFlg == "EA" AND itemid == "telno"` (L2328)

> Phone number registration conflict. The template ID `EZM0121D010` corresponds to the phone number registration SC (電話番号登録). The error flag `EA` (`RELATION_CHECK_ERR_EA`) indicates an entity-attribute check error. The item `telno` confirms this is a phone number field error. This means a phone number mask has detected that the same phone number record already exists in the system.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[TEMPLATEID_FUSV004203SC = "EZM0121D010"] AND [JFUStrConst.RELATION_CHECK_ERR_EA = "EA"] AND [ITEMID_TELNO = "telno"]` |

**Block 3.1.1** — [IF] `funcCode == "2"` (`JPCModelConstant.FUNC_CD_2`, Check-only button) (L2332)

> When the user pressed the Check button (not Submit), show a field-level error so they can correct the phone number.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[JPCModelConstant.FUNC_CD_2 = "2"]` // Check button press (確認ボタン押下時) |
| 2 | EXEC | `JFUWebCommon.setMessageInfo(this, MSGID_TELNO_ERR, new String[]{replaceTxt}, ITEMID_TELNO)` // Set field-level error message for phone number |
| 3 | RETURN | `return` // Handled |

**Block 3.1.2** — [ELSE] (L2338)

> When the user pressed Submit (not check-only), this is a real conflict — throw an update-not-allowed business exception.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0204)` // "0204" Update not allowed error (更新不可エラー) |

**Block 3.2** — [IF] `templateid == "ETU0071A010" AND itemid == "key_judge_kyoku_no" AND errFlg == "EA"` (L2344)

> Number portability verification area agreement error. Template `ETU0071A010` is the number portability verification area agreement (番号ポータビリティ可能エリア同意照会). The error item `key_judge_kyoku_no` (`ERROR_COLUMN_ETU0071A010`) refers to the carrier office number check field. The error flag `EA` indicates an entity-attribute check error.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[TEMPLATE_ID_ETU0071A010 = "ETU0071A010"] AND [ERROR_COLUMN_ETU0071A010 = "key_judge_kyoku_no"] AND [JFUStrConst.RELATION_CHECK_ERR_EA = "EA"]` |

**Block 3.2.1** — [IF] `funcCode == "2"` (`JPCModelConstant.FUNC_CD_2`, Check-only) (L2348)

> Check-only mode: show field-level error for correction.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[JPCModelConstant.FUNC_CD_2 = "2"]` // Check button press |
| 2 | EXEC | `JFUWebCommon.setMessageInfo(this, MSGID_TELNO_ERR, new String[]{replaceTxt}, ITEMID_TELNO)` // Set field-level error for phone number |
| 3 | RETURN | `return` // Handled |

**Block 3.2.2** — [ELSE] (L2354)

> Submit mode: throw update-not-allowed error.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0204)` // "0204" Update not allowed error |

**Block 3.3** — [IF] `errFlg == "EA" AND itemid == "upd_dtm_bf"` (L2360)

> Timestamp stamp check (タイムスタンプチェック). The error flag is `EA` (entity-attribute check error) and the item is `upd_dtm_bf` (upd_dtm_bf = update datetime before, 更新年月日時分秒(更新前)). This indicates an optimistic lock conflict — the record was modified by another user since it was loaded.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[JFUStrConst.RELATION_CHECK_ERR_EA = "EA"] AND [ITEMID_UPD_DTM_BF = "upd_dtm_bf"]` // Timestamp stamp check (タイムスタンプチェック) |
| 2 | LOG | `DEBUG_LOG.info(" Service IF execution error (conflict error)")` // Log: サービスIF実行結果エラー (排他エラー) |
| 3 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0204)` // "0204" Update not allowed error |

**Block 4** — [IF] `status == 1300` (`JPCModelConstant.TEMPLATE_CORRELATION_ERR`, External schema correlation check error) (L2368)

> Handles external schema correlation errors. If the item ID is `ido_div` (migration division, 異動区分), this is a contract state error — the service contract has a state that prevents this operation.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[JPCModelConstant.TEMPLATE_CORRELATION_ERR = "1300"]` // External schema correlation check error |

**Block 4.1** — [IF] `itemid == "ido_div"` (L2370)

> The error item is `ido_div` (異動区分, migration/district division). This is a business-common exception (業務共通例外) — the contract state is incompatible. Throw contract state error code `0102`.

| # | Type | Code |
|---|------|------|
| 1 | IF | `[ITEMID_IDO_DIV = "ido_div"]` // Migration division (異動区分) |
| 2 | LOG | `DEBUG_LOG.info(" Service IF execution error (migration division error)")` // Log: サービスIF実行結果エラー (異動区分エラー) |
| 3 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` // "0102" Contract state error (契約状態エラー) |

**Block 5** — [DEFAULT / FALL-THROUGH] (L2375-L2378)

> Any error status that does not match the above cases. These are screen-irrecoverable errors treated as system-level errors.

| # | Type | Code |
|---|------|------|
| 1 | LOG | `DEBUG_LOG.info(" Service IF execution error (system error)")` // Log: サービスIF実行結果エラー (システムエラー) |
| 2 | EXEC | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002)` // "0002" System error (システムエラー) |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `status` | Field | Error status code returned by the service layer: 1000 = single-item check, 1100 = internal schema check, 1300 = external schema correlation, 1400 = concept schema check |
| `templateid` | Field | Error template ID — identifies which screen/error definition generated the exception (e.g., `EZM0121D010` for phone number registration) |
| `itemid` | Field | Error item ID — identifies which input field triggered the error (e.g., `telno` = phone number, `ido_div` = migration division) |
| `errFlg` | Field | Error flag — the type of check failure (e.g., `E3` = digit format error, `EA` = entity-attribute relation check error) |
| `funcCode` | Field | Function code indicating the current screen mode: `"2"` = check-only mode (pressing the Check button), other values = submit mode |
| `telno` | Field | Phone number (電話番号) — the customer's phone number field |
| `key_telno` | Field | KEY phone number (KEY 電話番号) — the validated/formatted phone number key |
| `ido_div` | Field | Migration division (異動区分) — indicates a service contract status change/migration classification |
| `upd_dtm_bf` | Field | Update datetime before (更新年月日時分秒(更新前)) — the original timestamp of a record before an update attempt; used for optimistic locking |
| `key_judge_kyoku_no` | Field | Carrier office number judgment (判定局番号) — the telecom exchange/office number used in number portability verification |
| SINGLEDATA_ERR | Constant | Status code 1000 — single-item validation error (単項目チェックエラー) |
| RELATION_ERR | Constant | Status code 1100 — internal schema related check error (内部スキーマ関連チェックエラー) |
| ENTITY_RELATION_ERR | Constant | Status code 1400 — concept schema related check error (概念スキーマ関連チェックエラー) |
| TEMPLATE_CORRELATION_ERR | Constant | Status code 1300 — external schema correlation check error (外部スキーマの関連チェックエラー) |
| KETA_ERR | Constant | Error flag `E3` — digit format error (桁数エラー), phone number must have exact digit count |
| RELATION_CHECK_ERR_EA | Constant | Error flag `EA` — entity-attribute relation check error (関連チェックエラー) |
| FUNC_CD_2 | Constant | Function code `2` — check-only mode (確認のみ), triggered when user presses the Check button |
| ERROR_CODE_0204 | Constant | Error code `"0204"` — update not allowed (更新不可エラー), typically optimistic lock conflict or duplicate record |
| ERROR_CODE_0102 | Constant | Error code `"0102"` — contract state error (契約状態エラー), service contract has incompatible state for the requested operation |
| ERROR_CODE_0002 | Constant | Error code `"0002"` — system error (システムエラー), unrecoverable error displayed as generic system failure |
| MSGID_TELNO_ERR | Constant | Message ID `EKF1900-KW` — phone number error message for single-item check errors |
| DISPTEXT_TELNO_ERR | Constant | Display text key `REP_EKF1900-KW` — replacement text for the phone number error message |
| ETU0101B010 | Constant | Template ID for number portability check NTT reception office list (同番移転チェック用届別NTT収容局一覧照会) |
| EZM0121D010 | Constant | Template ID for phone number registration (電話番号登録) |
| ETU0071A010 | Constant | Template ID for number portability verification area agreement (番号ポータビリティ可能エリア同意照会) |
| MSKM | Acronym | Multi-Service Keyword Management — the web service processing module for second-number service applications |
| JCCWebServiceException | Class | Web service exception wrapper containing structured error metadata (message list, more info) from the service layer |
| JCCBusinessException | Class | Business exception thrown with a specific error code for screen-level error handling |
| Check button (確認ボタン) | UI term | Button that validates entered data without submitting — in this context, funcCode is set to "2" |
| Submit (送信) | UI term | Button that submits the completed form for processing — funcCode is set to a different value |
| Optimistic lock | Technical concept | Concurrency control mechanism using timestamps (upd_dtm_bf) to detect conflicting updates |
| Phone number mask (電話番号マスク) | UI component | System component that detects if a phone number already exists in the database |
