changeset 578:60c549d43988

remove LuanState.exception()
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 14 Jul 2015 17:40:48 -0600
parents d7a85fbe15f1
children f22a09e98b04
files core/src/luan/LuanException.java core/src/luan/LuanJavaFunction.java core/src/luan/LuanPropertyMeta.java core/src/luan/LuanState.java core/src/luan/LuanTable.java core/src/luan/impl/BinaryOpExpr.java core/src/luan/impl/FnCall.java core/src/luan/impl/LeExpr.java core/src/luan/impl/LenExpr.java core/src/luan/impl/LuanCompiler.java core/src/luan/impl/SetTableEntry.java core/src/luan/impl/UnmExpr.java core/src/luan/modules/BasicLuan.java core/src/luan/modules/HtmlLuan.java core/src/luan/modules/IoLuan.java core/src/luan/modules/JavaLuan.java core/src/luan/modules/PackageLuan.java core/src/luan/modules/PickleClient.java core/src/luan/modules/PickleCon.java core/src/luan/modules/StringLuan.java core/src/luan/modules/TableLuan.java core/src/luan/modules/Utils.java http/src/luan/modules/http/HttpServicer.java lucene/src/luan/modules/lucene/LuceneIndex.java mail/src/luan/modules/mail/SmtpCon.java
diffstat 25 files changed, 93 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/LuanException.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/LuanException.java	Tue Jul 14 17:40:48 2015 -0600
@@ -11,7 +11,7 @@
 		super(msg,cause);
 	}
 
-	LuanException(LuanState luan,Object msg) throws LuanException {
+	public LuanException(LuanState luan,Object msg) throws LuanException {
 		this( luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
 		table.rawPut( "java", this );
 		table.rawPut( "message", msg );
--- a/core/src/luan/LuanJavaFunction.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/LuanJavaFunction.java	Tue Jul 14 17:40:48 2015 -0600
@@ -94,7 +94,7 @@
 				throw (Error)cause;
 			if( cause instanceof LuanException )
 				throw (LuanException)cause;
-			throw luan.exception(cause);
+			throw new LuanException(luan,cause);
 		} catch(InstantiationException e) {
 			throw new RuntimeException(e);
 		}
@@ -131,10 +131,10 @@
 					expected = fixType(paramType.getSimpleName());
 				if( arg==null ) {
 					if( paramType.isPrimitive() )
-						throw luan.exception("bad argument #"+(i+1-start)+" ("+expected+" expected, got nil)");
+						throw new LuanException(luan,"bad argument #"+(i+1-start)+" ("+expected+" expected, got nil)");
 				} else {
 					String got = fixType(arg.getClass().getSimpleName());
-					throw luan.exception("bad argument #"+(i+1-start)+" ("+expected+" expected, got "+got+")");
+					throw new LuanException(luan,"bad argument #"+(i+1-start)+" ("+expected+" expected, got "+got+")");
 				}
 			}
 		}
--- a/core/src/luan/LuanPropertyMeta.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/LuanPropertyMeta.java	Tue Jul 14 17:40:48 2015 -0600
@@ -26,7 +26,7 @@
 		if( obj == null )
 			return null;
 		if( !(obj instanceof LuanFunction) )
-			throw luan.exception("get for '"+key+"' isn't a function");
+			throw new LuanException(luan,"get for '"+key+"' isn't a function");
 		LuanFunction fn = (LuanFunction)obj;
 		return fn.call(luan);
 	}
@@ -59,7 +59,7 @@
 			return;
 		}
 		if( !(obj instanceof LuanFunction) )
-			throw luan.exception("set for '"+key+"' isn't a function");
+			throw new LuanException(luan,"set for '"+key+"' isn't a function");
 		LuanFunction fn = (LuanFunction)obj;
 		fn.call(luan,new Object[]{value});
 	}
--- a/core/src/luan/LuanState.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/LuanState.java	Tue Jul 14 17:40:48 2015 -0600
@@ -65,15 +65,10 @@
 	}
 
 
-
-	public LuanException exception(Object msg) throws LuanException {
-		return new LuanException(this,msg);
-	}
-
 	public Boolean checkBoolean(Object obj) throws LuanException {
 		if( obj instanceof Boolean )
 			return (Boolean)obj;
-		throw exception( "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a boolean" );
+		throw new LuanException(this, "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a boolean" );
 	}
 
 	public Boolean checkBoolean(Object obj,LuanElement el) throws LuanException {
@@ -88,13 +83,13 @@
 	public String checkString(Object obj) throws LuanException {
 		if( obj instanceof String )
 			return (String)obj;
-		throw exception( "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a string" );
+		throw new LuanException(this, "attempt to use '"+context()+"' (a " + Luan.type(obj) + " value) as a string" );
 	}
 
 	public LuanFunction checkFunction(Object obj) throws LuanException {
 		if( obj instanceof LuanFunction )
 			return (LuanFunction)obj;
-		throw exception( "attempt to call '"+context()+"' (a " + Luan.type(obj) + " value)" );
+		throw new LuanException(this, "attempt to call '"+context()+"' (a " + Luan.type(obj) + " value)" );
 	}
 
 	public boolean isLessThan(Object o1,Object o2) throws LuanException {
@@ -111,7 +106,7 @@
 		LuanFunction fn = getBinHandler("__lt",o1,o2);
 		if( fn != null )
 			return checkBoolean( Luan.first(fn.call(this,new Object[]{o1,o2})) );
-		throw exception( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
+		throw new LuanException(this, "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
 	}
 
 	public String toString(Object obj) throws LuanException {
@@ -144,7 +139,7 @@
 		}
 		if( obj != null && hasJava() )
 			return JavaLuan.__index(this,obj,key,false);
-		throw exception( "attempt to index a " + Luan.type(obj) + " value in '"+context()+"'" );
+		throw new LuanException(this, "attempt to index a " + Luan.type(obj) + " value in '"+context()+"'" );
 	}
 
 	public String context() {
@@ -183,7 +178,7 @@
 	public Number checkNumber(Object obj) throws LuanException {
 		if( obj instanceof Number )
 			return (Number)obj;
-		throw exception( "attempt to perform arithmetic on '"+context()+"' (a " + Luan.type(obj) + " value)" );
+		throw new LuanException(this, "attempt to perform arithmetic on '"+context()+"' (a " + Luan.type(obj) + " value)" );
 	}
 */
 }
--- a/core/src/luan/LuanTable.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/LuanTable.java	Tue Jul 14 17:40:48 2015 -0600
@@ -160,7 +160,7 @@
 			tbl.put(luan,key,value);
 			return;
 		}
-		throw luan.exception("invalid type "+Luan.type(h)+" for metamethod __new_index");
+		throw new LuanException(luan,"invalid type "+Luan.type(h)+" for metamethod __new_index");
 	}
 
 	public void rawPut(Object key,Object val) {
@@ -319,14 +319,14 @@
 				LuanFunction fn = (LuanFunction)h;
 				Object obj = Luan.first(fn.call(luan,new Object[]{this}));
 				if( !(obj instanceof LuanFunction) )
-					throw luan.exception( "metamethod __pairs should return function but returned " + Luan.type(obj) );
+					throw new LuanException(luan, "metamethod __pairs should return function but returned " + Luan.type(obj) );
 				return (LuanFunction)obj;
 			}
 			if( h instanceof LuanMeta ) {
 				LuanMeta meta = (LuanMeta)h;
 				return meta.__pairs(luan,this);
 			}
-			throw luan.exception( "invalid type of metamethod __pairs: " + Luan.type(h) );
+			throw new LuanException(luan, "invalid type of metamethod __pairs: " + Luan.type(h) );
 		}
 		return rawPairs();
 	}
--- a/core/src/luan/impl/BinaryOpExpr.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/BinaryOpExpr.java	Tue Jul 14 17:40:48 2015 -0600
@@ -24,7 +24,7 @@
 			if( fn != null )
 				return Luan.first(fn.call(luan,new Object[]{o1,o2}));
 			String type = !(o1 instanceof Number) ? Luan.type(o1) : Luan.type(o2);
-			throw luan.exception("attempt to perform arithmetic on a "+type+" value");
+			throw new LuanException(luan,"attempt to perform arithmetic on a "+type+" value");
 		} finally {
 			luan.pop();
 		}
--- a/core/src/luan/impl/FnCall.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/FnCall.java	Tue Jul 14 17:40:48 2015 -0600
@@ -36,7 +36,7 @@
 				if( h != null )
 					return call(luan,h,argVals);
 			}
-			throw luan.exception( "attempt to call '"+fnName+"' (a " + Luan.type(o) + " value)" );
+			throw new LuanException(luan, "attempt to call '"+fnName+"' (a " + Luan.type(o) + " value)" );
 		} finally {
 			luan.pop();
 		}
--- a/core/src/luan/impl/LeExpr.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/LeExpr.java	Tue Jul 14 17:40:48 2015 -0600
@@ -37,7 +37,7 @@
 			fn = luan.getBinHandler("__lt",o1,o2);
 			if( fn != null )
 				return !luan.checkBoolean( Luan.first(fn.call(luan,new Object[]{o2,o1})) );
-			throw luan.exception( "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
+			throw new LuanException(luan, "attempt to compare " + Luan.type(o1) + " with " + Luan.type(o2) );
 		} finally {
 			luan.pop();
 		}
--- a/core/src/luan/impl/LenExpr.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/LenExpr.java	Tue Jul 14 17:40:48 2015 -0600
@@ -26,7 +26,7 @@
 		luan.push(el,null);
 		try {
 			if( !(o instanceof LuanTable) )
-				throw luan.exception( "attempt to get length of a " + Luan.type(o) + " value" );
+				throw new LuanException(luan, "attempt to get length of a " + Luan.type(o) + " value" );
 			LuanTable t = (LuanTable)o;
 			return t.length(luan);
 		} finally {
--- a/core/src/luan/impl/LuanCompiler.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/LuanCompiler.java	Tue Jul 14 17:40:48 2015 -0600
@@ -33,7 +33,7 @@
 			return parser.RequiredModule();
 		} catch(ParseException e) {
 //e.printStackTrace();
-			throw luan.exception( e.getFancyMessage() );
+			throw new LuanException(luan, e.getFancyMessage() );
 		}
 	}
 
--- a/core/src/luan/impl/SetTableEntry.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/SetTableEntry.java	Tue Jul 14 17:40:48 2015 -0600
@@ -34,7 +34,7 @@
 			if( t != null && luan.hasJava() )
 				JavaLuan.__new_index(luan,t,key,value);
 			else
-				throw luan.exception( "attempt to index a " + Luan.type(t) + " value in '"+el.text()+"'" );
+				throw new LuanException(luan, "attempt to index a " + Luan.type(t) + " value in '"+el.text()+"'" );
 		} finally {
 			luan.pop();
 		}
--- a/core/src/luan/impl/UnmExpr.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/impl/UnmExpr.java	Tue Jul 14 17:40:48 2015 -0600
@@ -26,7 +26,7 @@
 					return Luan.first(fn.call(luan,new Object[]{o}));
 				}
 			}
-			throw luan.exception("attempt to perform arithmetic on a "+Luan.type(o)+" value");
+			throw new LuanException(luan,"attempt to perform arithmetic on a "+Luan.type(o)+" value");
 		} finally {
 			luan.pop();
 		}
--- a/core/src/luan/modules/BasicLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/BasicLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -39,7 +39,7 @@
 			fileName = "stdin:";
 		String src = PackageLuan.read(luan,fileName,addExtension);
 		if( src == null )
-			throw luan.exception( "file '"+fileName+"' not found" );
+			throw new LuanException(luan, "file '"+fileName+"' not found" );
 		return load(luan,src,fileName,null,false);
 	}
 
@@ -76,7 +76,7 @@
 	public static void set_metatable(LuanState luan,LuanTable table,LuanTable metatable) throws LuanException {
 		Utils.checkNotNull(luan,table);
 		if( table.getHandler("__metatable") != null )
-			throw luan.exception("cannot change a protected metatable");
+			throw new LuanException(luan,"cannot change a protected metatable");
 		table.setMetatable(metatable);
 	}
 
@@ -101,7 +101,7 @@
 			LuanTable t = (LuanTable)v;
 			return t.rawLength();
 		}
-		throw luan.exception( "bad argument #1 to 'raw_len' (table or string expected)" );
+		throw new LuanException(luan, "bad argument #1 to 'raw_len' (table or string expected)" );
 	}
 
 	public static String to_string(LuanState luan,Object v) throws LuanException {
@@ -109,7 +109,7 @@
 	}
 
 	public static LuanTable new_error(LuanState luan,Object msg) throws LuanException {
-		return luan.exception(msg).table();
+		return new LuanException(luan,msg).table();
 	}
 
 	public static String assert_string(LuanState luan,String v) throws LuanException {
@@ -151,7 +151,7 @@
 	public static LuanFunction range(LuanState luan,final double from,final double to,Double stepV) throws LuanException {
 		final double step = stepV==null ? 1.0 : stepV;
 		if( step == 0.0 )
-			throw luan.exception("bad argument #3 (step may not be zero)");
+			throw new LuanException(luan,"bad argument #3 (step may not be zero)");
 		return new LuanFunction() {
 			double v = from;
 
@@ -185,22 +185,22 @@
 		Utils.checkNotNull(luan,blocks);
 		Object obj = blocks.get(luan,1);
 		if( obj == null )
-			throw luan.exception("missing 'try' value");
+			throw new LuanException(luan,"missing 'try' value");
 		if( !(obj instanceof LuanFunction) )
-			throw luan.exception("bad 'try' value (function expected, got "+Luan.type(obj)+")");
+			throw new LuanException(luan,"bad 'try' value (function expected, got "+Luan.type(obj)+")");
 		LuanFunction tryFn = (LuanFunction)obj;
 		LuanFunction catchFn = null;
 		obj = blocks.get(luan,"catch");
 		if( obj != null ) {
 			if( !(obj instanceof LuanFunction) )
-				throw luan.exception("bad 'catch' value (function expected, got "+Luan.type(obj)+")");
+				throw new LuanException(luan,"bad 'catch' value (function expected, got "+Luan.type(obj)+")");
 			catchFn = (LuanFunction)obj;
 		}
 		LuanFunction finallyFn = null;
 		obj = blocks.get(luan,"finally");
 		if( obj != null ) {
 			if( !(obj instanceof LuanFunction) )
-				throw luan.exception("bad 'finally' value (function expected, got "+Luan.type(obj)+")");
+				throw new LuanException(luan,"bad 'finally' value (function expected, got "+Luan.type(obj)+")");
 			finallyFn = (LuanFunction)obj;
 		}
 		try {
--- a/core/src/luan/modules/HtmlLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/HtmlLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -284,7 +284,7 @@
 				LuanTable t = (LuanTable)o;
 				String type = (String)t.get(luan,"type");
 				if( type==null )
-					throw luan.exception( "no type in element of table for 'Html.to_string'" );
+					throw new LuanException(luan, "no type in element of table for 'Html.to_string'" );
 				if( type.equals("comment") ) {
 					buf.append( "<!--" ).append( t.get(luan,"text") ).append( "-->" );
 				} else if( type.equals("cdata") ) {
@@ -297,10 +297,10 @@
 					buf.append( t.get(luan,"text") );
 					buf.append( "</" ).append( tag.get(luan,"name") ).append( ">" );
 				} else {
-					throw luan.exception( "invalid element type for 'Html.to_string'" );
+					throw new LuanException(luan, "invalid element type for 'Html.to_string'" );
 				}
 			} else 
-				throw luan.exception( "invalid value ("+Luan.type(o)+") in table for 'Html.to_string'" );
+				throw new LuanException(luan, "invalid value ("+Luan.type(o)+") in table for 'Html.to_string'" );
 		}
 		return buf.toString();
 	}
--- a/core/src/luan/modules/IoLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/IoLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -122,7 +122,7 @@
 				try {
 					if( args.length > 0 ) {
 						if( args.length > 1 || !"close".equals(args[0]) )
-							throw luan.exception( "the only argument allowed is 'close'" );
+							throw new LuanException(luan, "the only argument allowed is 'close'" );
 						in.close();
 						return null;
 					}
@@ -131,7 +131,7 @@
 						in.close();
 					return rtn;
 				} catch(IOException e) {
-					throw luan.exception(e);
+					throw new LuanException(luan,e);
 				}
 			}
 		};
@@ -145,7 +145,7 @@
 				try {
 					if( args.length > 0 ) {
 						if( args.length > 1 || !"close".equals(args[0]) )
-							throw luan.exception( "the only argument allowed is 'close'" );
+							throw new LuanException(luan, "the only argument allowed is 'close'" );
 						in.close();
 						return null;
 					}
@@ -155,7 +155,7 @@
 					}
 					return a;
 				} catch(IOException e) {
-					throw luan.exception(e);
+					throw new LuanException(luan,e);
 				}
 			}
 		};
@@ -272,7 +272,7 @@
 				out.close();
 				return;
 			}
-			throw luan.exception( "bad argument #1 to 'write' (string or binary expected)" );
+			throw new LuanException(luan, "bad argument #1 to 'write' (string or binary expected)" );
 		}
 
 		public LuanTable text_writer() throws IOException {
@@ -585,13 +585,13 @@
 	public static LuanTable uri(LuanState luan,String name,Boolean addExtension) throws LuanException {
 		int i = name.indexOf(':');
 		if( i == -1 )
-			throw luan.exception( "invalid Io.uri name '"+name+"', missing scheme" );
+			throw new LuanException(luan, "invalid Io.uri name '"+name+"', missing scheme" );
 		String scheme = name.substring(0,i);
 		String location = name.substring(i+1);
 		LuanTable schemes = schemes(luan);
 		LuanFunction opener = (LuanFunction)schemes.get(luan,scheme);
 		if( opener == null )
-			throw luan.exception( "invalid scheme '"+scheme+"' in '"+name+"'" );
+			throw new LuanException(luan, "invalid scheme '"+scheme+"' in '"+name+"'" );
 		return (LuanTable)Luan.first(opener.call(luan,new Object[]{location,addExtension}));
 	}
 
@@ -649,7 +649,7 @@
 	public static LuanTable socket(LuanState luan,String name) throws LuanException, IOException {
 		int i = name.indexOf(':');
 		if( i == -1 )
-			throw luan.exception( "invalid socket '"+name+"', format is: <host>:<port>" );
+			throw new LuanException(luan, "invalid socket '"+name+"', format is: <host>:<port>" );
 		String host = name.substring(0,i);
 		String portStr = name.substring(i+1);
 		int port = Integer.parseInt(portStr);
@@ -663,13 +663,13 @@
 				try {
 					if( args.length > 0 ) {
 						if( args.length > 1 || !"close".equals(args[0]) )
-							throw luan.exception( "the only argument allowed is 'close'" );
+							throw new LuanException(luan, "the only argument allowed is 'close'" );
 						ss.close();
 						return null;
 					}
 					return new LuanSocket(ss.accept()).table();
 				} catch(IOException e) {
-					throw luan.exception(e);
+					throw new LuanException(luan,e);
 				}
 			}
 		};
--- a/core/src/luan/modules/JavaLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/JavaLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -43,7 +43,7 @@
 
 	private static void checkJava(LuanState luan) throws LuanException {
 		if( !luan.hasJava() )
-			throw luan.exception("Java isn't allowed");
+			throw new LuanException(luan,"Java isn't allowed");
 	}
 
 	static final Object FAIL = new Object();
@@ -94,7 +94,7 @@
 				if( i != null ) {
 					return Array.get(obj,i);
 				}
-//				throw luan.exception("invalid member '"+key+"' for java array: "+obj);
+//				throw new LuanException(luan,"invalid member '"+key+"' for java array: "+obj);
 			} else if( key instanceof String ) {
 				String name = (String)key;
 				if( "instanceof".equals(name) ) {
@@ -110,7 +110,7 @@
 //System.out.println("invalid member '"+key+"' for java object: "+obj);
 		if( canReturnFail )
 			return FAIL;
-		throw luan.exception( "invalid index for java "+cls+" in '"+luan.context()+"'" );
+		throw new LuanException(luan, "invalid index for java "+cls+" in '"+luan.context()+"'" );
 	}
 
 	private static Object member(Object obj,List<Member> members) throws LuanException {
@@ -156,7 +156,7 @@
 					return;
 				}
 			}
-//			throw luan.exception("invalid member '"+key+"' for: "+obj);
+//			throw new LuanException(luan,"invalid member '"+key+"' for: "+obj);
 		} else {
 			cls = obj.getClass();
 			if( cls.isArray() ) {
@@ -165,7 +165,7 @@
 					Array.set(obj,i,value);
 					return;
 				}
-//				throw luan.exception("invalid member '"+key+"' for java array: "+obj);
+//				throw new LuanException(luan,"invalid member '"+key+"' for java array: "+obj);
 			} else if( key instanceof String ) {
 				String name = (String)key;
 				List<Member> members = getMembers(cls,name);
@@ -177,7 +177,7 @@
 				}
 			}
 		}
-		throw luan.exception( "invalid index for java "+cls+" in '"+luan.context()+"'" );
+		throw new LuanException(luan, "invalid index for java "+cls+" in '"+luan.context()+"'" );
 	}
 
 	private static void setMember(Object obj,List<Member> members,Object value) {
@@ -378,7 +378,7 @@
 					return fn.rawCall(luan,args);
 				} catch(IllegalArgumentException e) {}
 			}
-			throw luan.exception("no method matched args: "+Arrays.asList(args));
+			throw new LuanException(luan,"no method matched args: "+Arrays.asList(args));
 		}
 	}
 
@@ -415,7 +415,7 @@
 			if( !cls.isInstance(v) ) {
 				String got = v.getClass().getSimpleName();
 				String expected = cls.getSimpleName();
-				throw luan.exception("bad argument #1 ("+expected+" expected, got "+got+")");
+				throw new LuanException(luan,"bad argument #1 ("+expected+" expected, got "+got+")");
 			}
 			return v;
 		}
--- a/core/src/luan/modules/PackageLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/PackageLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -35,7 +35,7 @@
 	public static Object require(LuanState luan,String modName) throws LuanException {
 		Object mod = load(luan,modName);
 		if( mod==null )
-			throw luan.exception( "module '"+modName+"' not found" );
+			throw new LuanException(luan, "module '"+modName+"' not found" );
 		return mod;
 	}
 
@@ -57,7 +57,7 @@
 					mod = loaded.rawGet(modName);
 					if( mod != null )
 						return mod;
-					throw luan.exception( "module '"+modName+"' returned nil" );
+					throw new LuanException(luan, "module '"+modName+"' returned nil" );
 				}
 			}
 			loaded.rawPut(modName,mod);
--- a/core/src/luan/modules/PickleClient.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/PickleClient.java	Tue Jul 14 17:40:48 2015 -0600
@@ -53,7 +53,7 @@
 		} else {
 			String msg = (String)result[1];
 			String src = (String)result[2];
-			throw con.luan.exception(
+			throw new LuanException(con.luan,
 				msg + "\n"
 				+ "in:\n"
 				+ "------------------\n"
--- a/core/src/luan/modules/PickleCon.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/PickleCon.java	Tue Jul 14 17:40:48 2015 -0600
@@ -48,7 +48,7 @@
 		while( i < size ) {
 			int n = in.read(a,i,size-i);
 			if( n == -1 )
-//				throw luan.exception( "end of stream" );
+//				throw new LuanException(luan, "end of stream" );
 				throw new EOFException();
 			i += n;
 		}
@@ -83,7 +83,7 @@
 			binaries.add(a);
 			return "_binaries[" + binaries.size() + "]";
 		}
-		throw luan.exception( "invalid type: " + obj.getClass() );
+		throw new LuanException(luan, "invalid type: " + obj.getClass() );
 	}
 
 	private String pickle(Object obj,Set<LuanTable> set) throws LuanException {
@@ -92,7 +92,7 @@
 
 	private String pickle(LuanTable tbl,Set<LuanTable> set) throws LuanException {
 		if( !set.add(tbl) ) {
-			throw luan.exception( "circular reference in table" );
+			throw new LuanException(luan, "circular reference in table" );
 		}
 		StringBuilder sb = new StringBuilder();
 		sb.append( "{" );
--- a/core/src/luan/modules/StringLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/StringLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -202,7 +202,7 @@
 			m.appendTail(sb);
 			return new Object[]{ sb.toString(), i };
 		}
-		throw luan.exception( "bad argument #3 to 'gsub' (string/function/table expected)" );
+		throw new LuanException(luan, "bad argument #3 to 'gsub' (string/function/table expected)" );
 	}
 
 	// note - String.format() is too stupid to convert between ints and floats.
--- a/core/src/luan/modules/TableLuan.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/TableLuan.java	Tue Jul 14 17:40:48 2015 -0600
@@ -34,13 +34,13 @@
 
 	public static void insert(LuanState luan,LuanTable list,int pos,Object value) throws LuanException {
 		if( list.getMetatable() != null )
-			throw luan.exception("can't insert into a table with a metatable");
+			throw new LuanException(luan,"can't insert into a table with a metatable");
 		list.rawInsert(pos,value);
 	}
 
 	public static Object remove(LuanState luan,LuanTable list,int pos) throws LuanException {
 		if( list.getMetatable() != null )
-			throw luan.exception("can't remove from a table with a metatable");
+			throw new LuanException(luan,"can't remove from a table with a metatable");
 		return list.rawRemove(pos);
 	}
 
@@ -50,7 +50,7 @@
 
 	public static void sort(final LuanState luan,LuanTable list,final LuanFunction comp) throws LuanException {
 		if( list.getMetatable() != null )
-			throw luan.exception("can't sort a table with a metatable");
+			throw new LuanException(luan,"can't sort a table with a metatable");
 		final LessThan lt;
 		if( comp==null ) {
 			lt = new LessThan() {
--- a/core/src/luan/modules/Utils.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/core/src/luan/modules/Utils.java	Tue Jul 14 17:40:48 2015 -0600
@@ -20,7 +20,7 @@
 
 	private static void checkNotNull(LuanState luan,Object v,String expected) throws LuanException {
 		if( v == null )
-			throw luan.exception("bad argument #1 ("+expected+" expected, got nil)");
+			throw new LuanException(luan,"bad argument #1 ("+expected+" expected, got nil)");
 	}
 
 	public static void checkNotNull(LuanState luan,String s) throws LuanException {
--- a/http/src/luan/modules/http/HttpServicer.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/http/src/luan/modules/http/HttpServicer.java	Tue Jul 14 17:40:48 2015 -0600
@@ -51,7 +51,7 @@
 			if( mod==null )
 				return false;
 			if( !(mod instanceof LuanFunction) )
-				throw luan.exception( "module '"+modName+"' must return a function" );
+				throw new LuanException(luan, "module '"+modName+"' must return a function" );
 			if( Boolean.TRUE.equals(per_session_pages.rawGet(mod)) ) {
 				HttpSession session = request.getSession();
 				LuanState sessionLuan  = (LuanState)session.getValue("luan");
--- a/lucene/src/luan/modules/lucene/LuceneIndex.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/lucene/src/luan/modules/lucene/LuceneIndex.java	Tue Jul 14 17:40:48 2015 -0600
@@ -135,7 +135,7 @@
 
 	public void save(LuanState luan,LuanTable doc) throws LuanException, IOException {
 		if( doc.get(luan,"type")==null )
-			throw luan.exception("missing 'type' field");
+			throw new LuanException(luan,"missing 'type' field");
 		Long id = (Long)doc.get(luan,"id");
 
 		boolean commit = !writeLock.isHeldByCurrentThread();
@@ -212,7 +212,7 @@
 
 	public void backup(LuanState luan,String zipFile) throws LuanException, IOException {
 		if( !zipFile.endsWith(".zip") )
-			throw luan.exception("file "+zipFile+" doesn't end with '.zip'");
+			throw new LuanException(luan,"file "+zipFile+" doesn't end with '.zip'");
 		IndexCommit ic = snapshotDeletionPolicy.snapshot();
 		try {
 			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
@@ -265,7 +265,7 @@
 			try {
 				return toTable(luan,searcher.doc(docID));
 			} catch(IOException e) {
-				throw luan.exception(e);
+				throw new LuanException(luan,e);
 			}
 		}
 	}
@@ -309,7 +309,7 @@
 		try {
 			if( fn!=null && n==null ) {
 				if( sortStr != null )
-					throw luan.exception("sort must be nil when n is nil");
+					throw new LuanException(luan,"sort must be nil when n is nil");
 				final DocFn docFn = new DocFn(searcher);
 				MyCollector col = new MyCollector() {
 					@Override public void collect(int doc) {
@@ -350,7 +350,7 @@
 
 	public Object search_in_transaction(LuanState luan,LuanFunction fn) throws LuanException, IOException {
 		if( threadLocalSearcher.get() != null )
-			throw luan.exception("can't nest search_in_transaction calls");
+			throw new LuanException(luan,"can't nest search_in_transaction calls");
 		IndexSearcher searcher = openSearcher();
 		threadLocalSearcher.set(searcher);
 		try {
@@ -375,14 +375,14 @@
 
 		@Override public void __new_index(LuanState luan,LuanTable tbl,Object key,Object value) throws LuanException {
 			if( !(key instanceof String) )
-				throw luan.exception("key must be string");
+				throw new LuanException(luan,"key must be string");
 			String field = (String)key;
 			if( value==null ) {  // delete
 				mfp.fields.remove(field);
 				return;
 			}
 			if( !(value instanceof FieldParser) )
-				throw luan.exception("value must be FieldParser like the values of Lucene.type");
+				throw new LuanException(luan,"value must be FieldParser like the values of Lucene.type");
 			FieldParser parser = (FieldParser)value;
 			mfp.fields.put( field, parser );
 		}
@@ -406,7 +406,7 @@
 		for( Map.Entry<Object,Object> entry : table.iterable(luan) ) {
 			Object key = entry.getKey();
 			if( !(key instanceof String) )
-				throw luan.exception("key must be string");
+				throw new LuanException(luan,"key must be string");
 			String name = (String)key;
 			Object value = entry.getValue();
 			if( value instanceof String ) {
@@ -441,7 +441,7 @@
 				byte[] b = (byte[])value;
 				doc.add(new StoredField(name, b));
 			} else
-				throw luan.exception("invalid value type "+value.getClass()+"' for '"+name+"'");
+				throw new LuanException(luan,"invalid value type "+value.getClass()+"' for '"+name+"'");
 		}
 		return doc;
 	}
@@ -467,7 +467,7 @@
 				table.rawPut(name,s);
 				continue;
 			}
-			throw luan.exception("invalid field type for "+ifld);
+			throw new LuanException(luan,"invalid field type for "+ifld);
 		}
 		return table;
 	}
--- a/mail/src/luan/modules/mail/SmtpCon.java	Mon Jul 13 20:53:02 2015 -0600
+++ b/mail/src/luan/modules/mail/SmtpCon.java	Tue Jul 14 17:40:48 2015 -0600
@@ -30,7 +30,7 @@
 
 		String host = getString(luan,params,"host");
 		if( host==null )
-			throw luan.exception( "parameter 'host' is required" );
+			throw new LuanException(luan, "parameter 'host' is required" );
 		props.setProperty("mail.smtp.host",host);
 
 		Object port = params.remove("port");
@@ -41,10 +41,10 @@
 			} else if( port instanceof Number ) {
 				Integer i = Luan.asInteger(port);
 				if( i == null )
-					throw luan.exception( "parameter 'port' must be an integer" );
+					throw new LuanException(luan, "parameter 'port' must be an integer" );
 				s = i.toString();
 			} else {
-				throw luan.exception( "parameter 'port' must be an integer" );
+				throw new LuanException(luan, "parameter 'port' must be an integer" );
 			}
 			props.setProperty("mail.smtp.socketFactory.port", s);
 			props.setProperty("mail.smtp.port", s);
@@ -56,7 +56,7 @@
 		} else {
 			String password = getString(luan,params,"password");
 			if( password==null )
-				throw luan.exception( "parameter 'password' is required with 'username'" );
+				throw new LuanException(luan, "parameter 'password' is required with 'username'" );
 			props.setProperty("mail.smtp.auth","true");
 			final PasswordAuthentication pa = new PasswordAuthentication(username,password);
 			Authenticator auth = new Authenticator() {
@@ -68,13 +68,13 @@
 		}
 
 		if( !params.isEmpty() )
-			throw luan.exception( "unrecognized parameters: "+params );
+			throw new LuanException(luan, "unrecognized parameters: "+params );
 	}
 
 	private String getString(LuanState luan,Map<Object,Object> params,String key) throws LuanException {
 		Object val = params.remove(key);
 		if( val!=null && !(val instanceof String) )
-			throw luan.exception( "parameter '"+key+"' must be a string" );
+			throw new LuanException(luan, "parameter '"+key+"' must be a string" );
 		return (String)val;
 	}
 
@@ -124,49 +124,49 @@
 						mp.addBodyPart(part);
 					}
 					if( !map.isEmpty() )
-						throw luan.exception( "invalid body types: " + map );
+						throw new LuanException(luan, "invalid body types: " + map );
 					bodyPart.setContent(mp);
 				} else
-					throw luan.exception( "parameter 'body' must be a string or table" );
+					throw new LuanException(luan, "parameter 'body' must be a string or table" );
 			}
 
 			if( attachments != null ) {
 				if( !(attachments instanceof LuanTable) )
-					throw luan.exception( "parameter 'attachments' must be a table" );
+					throw new LuanException(luan, "parameter 'attachments' must be a table" );
 				LuanTable attachmentsTbl = (LuanTable)attachments;
 				if( !attachmentsTbl.isList() )
-					throw luan.exception( "parameter 'attachments' must be a list" );
+					throw new LuanException(luan, "parameter 'attachments' must be a list" );
 				MimeMultipart mp = new MimeMultipart("mixed");
 				if( body != null )
 					mp.addBodyPart((MimeBodyPart)bodyPart);
 				for( Object attachment : attachmentsTbl.asList() ) {
 					if( !(attachment instanceof LuanTable) )
-						throw luan.exception( "each attachment must be a table" );
+						throw new LuanException(luan, "each attachment must be a table" );
 					Map<Object,Object> attachmentMap = new HashMap<Object,Object>(((LuanTable)attachment).asMap(luan));
 					Object obj;
 
 					obj = attachmentMap.remove("filename");
 					if( obj==null )
-						throw luan.exception( "an attachment is missing 'filename'" );
+						throw new LuanException(luan, "an attachment is missing 'filename'" );
 					if( !(obj instanceof String) )
-						throw luan.exception( "an attachment filename must be a string" );
+						throw new LuanException(luan, "an attachment filename must be a string" );
 					String filename = (String)obj;
 
 					obj = attachmentMap.remove("content_type");
 					if( obj==null )
-						throw luan.exception( "an attachment is missing 'content_type'" );
+						throw new LuanException(luan, "an attachment is missing 'content_type'" );
 					if( !(obj instanceof String) )
-						throw luan.exception( "an attachment content_type must be a string" );
+						throw new LuanException(luan, "an attachment content_type must be a string" );
 					String content_type = (String)obj;
 
 					Object content = attachmentMap.remove("content");
 					if( content==null )
-						throw luan.exception( "an attachment is missing 'content'" );
+						throw new LuanException(luan, "an attachment is missing 'content'" );
 					if( content_type.startsWith("text/") && content instanceof byte[] )
 						content = new String((byte[])content);
 
 					if( !attachmentMap.isEmpty() )
-						throw luan.exception( "unrecognized attachment parameters: "+attachmentMap );
+						throw new LuanException(luan, "unrecognized attachment parameters: "+attachmentMap );
 
 					MimeBodyPart part = new MimeBodyPart();
 					part.setContent(content,content_type);
@@ -177,11 +177,11 @@
 			}
 
 			if( !mailParams.isEmpty() )
-				throw luan.exception( "unrecognized parameters: "+mailParams );
+				throw new LuanException(luan, "unrecognized parameters: "+mailParams );
 
 			Transport.send(msg);
 		} catch(MessagingException e) {
-			throw luan.exception(e);
+			throw new LuanException(luan,e);
 		}
 	}