오류와 예외
어느 단계의 오류인가
섹션 제목: “어느 단계의 오류인가”오류를 처리하려면 먼저 문제가 발생한 단계를 구분해야 합니다. 선언한 타입이 맞지 않는 소스와 실행 중 연결이 끊기는 상황은 같은 방식으로 해결하지 않습니다.
| 단계 | 대표 상황 | 확인할 것 |
|---|---|---|
| 문법·의미 검사 | 알 수 없는 타입, 잘못된 인수, 반환 타입 불일치 | 소스의 이름·범위·접근·타입 |
| 빌드 | 런타임 심볼이나 필요한 도구를 찾지 못함 | 실제 빌드 진단 |
| 실행 | 종료 실패, 시간 제한 초과 | 종료 코드·실행 진단 |
| 결과 비교 | 종료는 됐지만 계산 결과가 다름 | 실제 stdout과 비교 기준 |
| 외부 기능 | 메시지를 못 받음, 데이터가 저장되지 않음 | 수신 측·데이터베이스의 실제 상태 |
문법 오류는 catch로 해결할 대상이 아닙니다. 해당 소스를 먼저 고쳐 검사와 빌드를 통과해야 합니다. 실행 버튼에서 실패가 발생하면 실제 오류 메시지가 자동으로 펼쳐집니다. 지원되지 않는 native 기능 때문에 중단되는 빌드는 소스 자체의 오류와 구분합니다.
메서드 계약에서 찾는 오류
섹션 제목: “메서드 계약에서 찾는 오류”int square(int value)는 정수 하나를 받아 정수를 반환하는 계약입니다. 문자열을 전달하거나 값을 반환하지 않는 본문은 계약에 맞지 않습니다.
| 검사 오류 | 소스에서 확인할 순서 |
|---|---|
Undefined variable |
선언 여부 → 철자 → 블록 범위 |
Cannot assign |
오른쪽 값의 타입 → 왼쪽 변수 타입 → null 허용 여부 |
No matching constructor |
생성자 접근 → 인수 개수 → 인수 타입·이름 |
No matching method |
호출 대상 타입 → 메서드 이름 → 매개변수 |
must return |
반환 타입 → 모든 종료 경로의 반환값 |
오류를 없애기 위해 타입을 무조건 var로 바꾸는 것은 적절한 해결이 아닐 수 있습니다. 추론된 타입에도 같은 대입·호출 규칙이 적용됩니다.
타입이 맞지 않는 대입을 확인하기
섹션 제목: “타입이 맞지 않는 대입을 확인하기”아래 소스는 int 변수에 문자열을 대입합니다. 빌드·실행을 누르면 실제 의미 검증의 Cannot assign string to int 진단을 볼 수 있습니다. 실행 실패와 달리 프로그램을 실행하기 전에 중단됩니다.
의도적인 빌드 실패 예제 — int 변수에 문자열을 대입해 빌드의 의미 검증 오류를 확인합니다.
class TypeAssignmentError {
static void main() {
int value = "oops";
print(value);
}
}public class TypeAssignmentError {
public static void main(String[] args) {
int value = "oops";
System.out.println(value);
}
}value: int = "oops"
print(value)Python의 타입 주석은 실행 시 대입을 거절하지 않습니다. 이 코드는 oops를 출력합니다. Unibase의 의미 검증 오류와 구분하세요.
using System;
class TypeAssignmentError {
static void Main() {
int value = "oops";
Console.WriteLine(value);
}
}const value: number = "oops";
console.log(value);package main
import (
"fmt"
)
func main() {
var value int = "oops"
fmt.Println(value)
}다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.
Unibase 실행 결과
빌드·실행 메시지
Unibase 탭의 빌드·실행을 누르면 실제 오류 메시지가 표시됩니다. 빌드에 실패하므로 실행 단계는 진행하지 않습니다.
확인한 진단과 단계별 결과 (2026-10-06)
실제 네이티브 검사: 빌드 failed · 실행 skipped · 실행 종료 코드 실행하지 않음
확인할 핵심 진단: Cannot assign string to int
unic: error: Semantic validation failed:
TypeAssignmentError.main.value: Cannot assign string to int variable 'value'.확인된 원본의 실제 빌드·실행 기록입니다. 버튼을 누르면 서버가 다시 빌드·실행하고 새 결과를 표시합니다.
다른 언어에서도 선언한 타입과 대입 값을 비교하세요. Python은 타입 주석만으로 실행 중 대입을 거절하지 않으므로 해당 탭의 차이도 함께 읽습니다.
범위 밖 접근과 오류 예방
섹션 제목: “범위 밖 접근과 오류 예방”항목이 하나인 List의 유효한 인덱스는 0입니다. 인덱스 1을 읽는 다음 프로그램은 빌드를 통과하지만 실행 중 Collection index out of range 진단과 종료 코드 1로 중단됩니다.
의도적인 실행 실패 예제 — 항목이 하나인 List에서 인덱스 1을 읽습니다.
import unibase.collections.List;
class ListIndexError {
static void main() {
List<string> colors = ["red"];
print(colors.get(1));
}
}import java.util.List;
public class ListIndexError {
public static void main(String[] args) {
List<String> colors = List.of("red");
System.out.println(colors.get(1));
}
}colors = ["red"]
print(colors[1])using System;
using System.Collections.Generic;
class ListIndexError {
static void Main() {
var colors = new List<string> { "red" };
Console.WriteLine(colors[1]);
}
}const colors = ["red"];
const index = 1;
if (index < 0 || index >= colors.length) {
throw new RangeError("index out of range");
}
console.log(colors[index]);JavaScript 배열의 범위 밖 접근은 undefined를 반환합니다. 같은 실패를 관찰하도록 범위를 검사하고 RangeError를 명시적으로 전달합니다.
package main
import (
"fmt"
)
func main() {
colors := []string{"red"}
fmt.Println(colors[1])
}다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.
Unibase 실행 결과
빌드·실행 메시지
Unibase 탭의 빌드·실행을 누르면 실제 오류 메시지가 표시됩니다. 빌드가 끝나도 실행은 실패할 수 있습니다.
확인한 진단과 단계별 결과 (2026-10-06)
실제 네이티브 검사: 빌드 passed · 실행 failed · 실행 종료 코드 1
확인할 핵심 진단: Collection index out of range
Unibase runtime error: Collection index out of range확인된 원본의 실제 빌드·실행 기록입니다. 버튼을 누르면 서버가 다시 빌드·실행하고 새 결과를 표시합니다.
현재 native 경로에서 이 오류를 catch로 복구하는 지원은 없습니다. 입력을 읽기 전에 범위를 검사하면 실패 경로에 진입하는 것을 예방할 수 있습니다.
오류를 예방하는 정상 실행 예제 — 항목을 읽기 전에 인덱스를 검사해 실행 오류를 예방합니다.
import unibase.collections.List;
class IndexGuard {
static void main() {
List<string> colors = ["red"];
int index = 1;
if (index >= 0 && index < colors.size()) {
print(colors.get(index));
} else {
print("index out of range");
}
}
}import java.util.List;
public class IndexGuard {
public static void main(String[] args) {
List<String> colors = List.of("red");
int index = 1;
if (index >= 0 && index < colors.size()) {
System.out.println(colors.get(index));
} else { System.out.println("index out of range"); }
}
}colors = ["red"]
index = 1
if 0 <= index < len(colors):
print(colors[index])
else:
print("index out of range")using System;
using System.Collections.Generic;
class IndexGuard {
static void Main() {
var colors = new List<string> { "red" };
int index = 1;
if (index >= 0 && index < colors.Count) {
Console.WriteLine(colors[index]);
} else { Console.WriteLine("index out of range"); }
}
}const colors = ["red"];
const index = 1;
if (index >= 0 && index < colors.length) {
console.log(colors[index]);
} else { console.log("index out of range"); }package main
import (
"fmt"
)
func main() {
colors := []string{"red"}
index := 1
if index >= 0 && index < len(colors) {
fmt.Println(colors[index])
} else {
fmt.Println("index out of range")
}
}다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.
Unibase 실행 결과
빌드·실행 메시지
출력 비교 기준
index out of range
확인한 진단과 단계별 결과 (2026-10-06)
실제 네이티브 검사: 빌드 passed · 실행 passed · 실행 종료 코드 0
index out of range확인된 원본의 실제 빌드·실행 기록입니다. 버튼을 누르면 서버가 다시 빌드·실행하고 새 결과를 표시합니다.
두 프로그램의 입력은 같습니다. 정상 예제는 조건이 거짓일 때 대체 안내를 출력하고 종료 코드 0으로 끝납니다. 안내 문자열이 같아 보여도 stderr와 stdout, 종료 코드를 구분해 읽어야 합니다. TypeScript 배열은 범위 밖 접근에서 undefined를 반환하므로 실패 탭은 명시적으로 RangeError를 전달합니다.
throw: 실패를 전달하는 문법
섹션 제목: “throw: 실패를 전달하는 문법”throw는 예외 값을 전달하는 문법입니다. 현재 선언에서 Exception은 메시지 필드를 보관하고, RuntimeException·TimeoutException·CancellationException은 예외 계층을 표현합니다.
현재 native 실행 환경에서 미지원 — 예외를 전달하는 문법이며 현재 native 빌드에서는 아직 실행할 수 없습니다.
class ThrowError {
static void main() {
throw Exception("operation failed");
}
}public class ThrowError {
public static void main(String[] args) {
throw new RuntimeException("operation failed");
}
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
raise RuntimeError("operation failed")이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
using System;
class ThrowError {
static void Main() {
throw new Exception("operation failed");
}
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
throw new Error("operation failed");이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
package main
func main() {
panic("operation failed")
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다. Go는 throw·catch 대신 panic과 defer·recover를 사용합니다.
다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.
Unibase 실행 결과
빌드·실행 메시지
Unibase 탭의 빌드·실행을 누르면 실제 오류 메시지가 표시됩니다. native 컴파일러의 예외 처리가 구현되지 않아 빌드가 중단됩니다. 소스의 타입 오류와 구분하세요.
확인한 진단과 단계별 결과 (2026-10-06)
실제 네이티브 검사: 빌드 failed · 실행 skipped · 실행 종료 코드 실행하지 않음
확인할 핵심 진단: does not support statement: throw
unic: error: Native LLVM lowering does not support statement: throw Exception("operation failed")확인된 원본의 실제 빌드·실행 기록입니다. 버튼을 누르면 서버가 다시 빌드·실행하고 새 결과를 표시합니다.
아무 값이나 throw하는 형태는 아닙니다. 현재 의미 검사에서 문자열을 그대로 throw하거나 예외가 아닌 타입을 catch하는 코드는 거절됩니다. 위 소스는 전체 프로그램이며, 현재 native 빌드에서 does not support statement: throw 진단으로 중단되는 것을 버튼으로 확인할 수 있습니다.
현재 문서의 native 실행 경로는 사용자 코드의 throw와 try/catch를 아직 지원하지 않습니다. 이러한 문장을 빌드하면 지원 범위를 설명하는 진단으로 중단합니다. 아래에서는 언어의 구문과 선언을 설명하며, 실행 서버에서 예외 복구가 동작한다고 보장하지 않습니다.
try/catch: 처리할 범위 정하기
섹션 제목: “try/catch: 처리할 범위 정하기”try에는 실패할 수 있는 호출을, catch에는 처리할 예외 타입과 변수 이름을 씁니다. catch 변수는 해당 처리 블록에서 사용합니다.
현재 native 실행 환경에서 미지원 — 예외를 잡아 operation failed를 출력하는 구조이며 현재 native 빌드에서는 아직 실행할 수 없습니다.
class TryCatchError {
static void main() {
try {
throw Exception("operation failed");
} catch (Exception error) {
print(error.message);
}
}
}public class TryCatchError {
public static void main(String[] args) {
try {
throw new RuntimeException("operation failed");
} catch (RuntimeException error) {
System.out.println(error.getMessage());
}
}
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
try:
raise RuntimeError("operation failed")
except RuntimeError as error:
print(str(error))이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
using System;
class TryCatchError {
static void Main() {
try {
throw new Exception("operation failed");
} catch (Exception error) {
Console.WriteLine(error.Message);
}
}
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
try {
throw new Error("operation failed");
} catch (error: unknown) {
if (error instanceof Error) { console.log(error.message); }
else { throw error; }
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다.
package main
import (
"fmt"
)
func main() {
defer func() {
if error := recover(); error != nil {
fmt.Println(error)
}
}()
panic("operation failed")
}이 언어의 예외 전달·처리 대응 코드입니다. 현재 Unibase native의 미지원 빌드 진단과 실행 결과가 다릅니다. Go는 throw·catch 대신 panic과 defer·recover를 사용합니다.
다른 언어의 탭은 직접 작성한 대응 코드이며 컴파일러의 자동 생성 결과가 아닙니다. 언어마다 API와 실행 환경이 다릅니다. 이 페이지의 빌드·실행은 Unibase 탭에서 사용할 수 있습니다.
Unibase 실행 결과
빌드·실행 메시지
Unibase 탭의 빌드·실행을 누르면 실제 오류 메시지가 표시됩니다. native 컴파일러의 예외 처리가 구현되지 않아 빌드가 중단됩니다. 소스의 타입 오류와 구분하세요.
확인한 진단과 단계별 결과 (2026-10-06)
실제 네이티브 검사: 빌드 failed · 실행 skipped · 실행 종료 코드 실행하지 않음
확인할 핵심 진단: Native exception handlers are not implemented
unic: error: Native exception handlers are not implemented확인된 원본의 실제 빌드·실행 기록입니다. 버튼을 누르면 서버가 다시 빌드·실행하고 새 결과를 표시합니다.
이 프로그램은 예외를 catch로 처리해 operation failed를 출력하고 정상 종료하는 구조입니다. 현재 Unibase native 빌드는 예외 처리가 구현되지 않아 Native exception handlers are not implemented 진단으로 중단합니다. 따라서 이 빌드 실패는 예외를 정상 처리한 결과가 아니며, 현재 컴파일러의 미지원 기능입니다. 다른 언어의 탭에서는 실제 예외를 전달하고 처리해 operation failed를 출력하는 대응 코드를 비교할 수 있습니다. Go의 panic·defer·recover는 클래스 기반 예외 문법과 구분합니다.
실패를 복구할 수 있는지, 호출자에게 전달해야 하는지 구분하세요. 오류를 무조건 삼킨 뒤 성공 메시지를 출력하면 작업이 끝났다는 잘못된 신호를 주게 됩니다. 현재 native 런타임의 범위 밖 인덱스·없는 맵 키·0 나눗셈 등은 stderr에 이유를 출력하고 종료 코드 1을 반환합니다. 이 실행 진단은 위 catch 블록으로 복구하는 경로와 구분됩니다.
비동기 작업의 실패와 취소
섹션 제목: “비동기 작업의 실패와 취소”Future의 결과를 기다리는 지점은 작업의 값 또는 실패를 확인할 위치입니다. isDone()은 결과가 정상인지와 같은 질문이 아닙니다. isCancelled()는 취소 상태 조회이며, cancel()의 요청이 언제 반영되는지는 런타임 계약에 따라 확인해야 합니다.
Promise<T>.complete(value)와 fail(Exception)은 완료와 실패를 표현하는 선언입니다. 이미 완료된 Promise의 중복 완료, 취소 이후 결과 접근과 timeout 예외 발생 조건은 확인한 계약 없이 특정 동작을 보장하지 않습니다.
실행 결과를 읽는 순서
섹션 제목: “실행 결과를 읽는 순서”버튼을 누른 뒤 상태 안내와 실제 stdout을 확인하세요. 빌드에 실패하면 프로그램을 실행하지 않았다는 안내와 실제 빌드 오류가 표시됩니다. 실행에 실패하면 종료 코드와 실제 실행 오류가 표시됩니다. 출력 불일치는 원본과 비교 기준·실행 환경을 함께 확인하세요. 예상 문자열을 대신 보여주는 방식으로 실패를 숨기지 않습니다.
Net은 상대편이 받은 데이터, SQL은 실제 조회한 데이터가 필요합니다. 본문 예제는 이 값을 실제로 비교합니다. 콘솔에 success를 출력한 것만으로 연결·전송·저장이 성공했다고 판단할 수는 없습니다. 지원 환경과 확인한 결과는 실행 확인 범위에 정리되어 있습니다.