Message from discussion
Exception Handling in RavenDb UnitOfWork
Received: by 10.68.227.230 with SMTP id sd6mr14198294pbc.8.1334687354684;
Tue, 17 Apr 2012 11:29:14 -0700 (PDT)
X-BeenThere: ravendb@googlegroups.com
Received: by 10.68.222.193 with SMTP id qo1ls22825442pbc.9.gmail; Tue, 17 Apr
2012 11:29:13 -0700 (PDT)
Received: by 10.68.203.132 with SMTP id kq4mr946937pbc.3.1334687353564;
Tue, 17 Apr 2012 11:29:13 -0700 (PDT)
Date: Tue, 17 Apr 2012 11:29:11 -0700 (PDT)
From: aa <albert.at...@gmail.com>
To: ravendb@googlegroups.com
Message-ID: <12834308.155.1334687351320.JavaMail.geo-discussion-forums@ynbq18>
In-Reply-To: <CABcSOXjuRU_aqDDdbDDrNpvetAjYKsFGL_UtjhCJwu7W5wjcBA@mail.gmail.com>
References: <6073595.673.1334608732000.JavaMail.geo-discussion-forums@ynje10>
<CAF0G-ZgPV8MLYxWtWsPbJote+8e4CxL47ujqiKmCmVcV9q+cgQ@mail.gmail.com>
<15276266.262.1334674776337.JavaMail.geo-discussion-forums@ynkl30>
<CABcSOXhnzhOd+f8a67=XFOn6+fTF=RefwkgPTgHyFEDejon9nQ@mail.gmail.com>
<33019810.87.1334683690295.JavaMail.geo-discussion-forums@ynll9>
<CABcSOXjF1sN=X-C8XqaeL9BfRXwq4bMtUY_5D_FfPJnqyE97kw@mail.gmail.com>
<11724521.50.1334685024548.JavaMail.geo-discussion-forums@ynll3>
<CABcSOXjuRU_aqDDdbDDrNpvetAjYKsFGL_UtjhCJwu7W5wjcBA@mail.gmail.com>
Subject: Re: [RavenDB] Exception Handling in RavenDb UnitOfWork
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_153_28365935.1334687351315"
------=_Part_153_28365935.1334687351315
Content-Type: multipart/alternative;
boundary="----=_Part_154_4908051.1334687351316"
------=_Part_154_4908051.1334687351316
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
This would have been much easier with one ExceptionType that encapsulates
all Raven related exceptions.
In any event handling (Exception) only is not ideal, there might be other
exceptions that the application might throw that I DO NOT want to catch.
There might be exceptions that might be thrown by ASP.NET itself that are
really unexpected and are supposed to make the app crash, if I handle
everything then there might be exceptions that get handled and logged but
the application stays running, running in an inconsistent state.
I would have to surround only session calls with a try to solve this, this
means I will need many try/catch blocks in each of my controller actions.
Its much easier/cleaner to catch one exception type that you know it comes
from raven.
On Tuesday, April 17, 2012 1:14:17 PM UTC-5, Ryan Heath wrote:
>
> How does it differ from this?
>
> public OperationResult Execute(String operationId)
> {
> _logger.Info(String.Format("Operation Manager: Adding a new task to
> the database for Operation with Id ({0})...", operationId));
> using(var session = _documentStore.OpenSession())
> {
> try
> {
> Operation operation = session.Get<Operation>(operationId);
> Task task = session.CreateTaskFromOperation();
> session.Store(task);
> session.SaveChanges();
> Bus.SendLocal(new BeginTask() { TaskId = task.Id });
> TaskDto taskDto = Mapper.Map<Task, TaskDto>(task);
> return new OperationResult.OK(taskDto);
> }
> catch (Exception e)
> {
> _logger.Error(e.Message,e);
> if !(e is InvalidOperationException) ? return new
> OperationResult.InternalServerError() :
> return new OperationResult.BadRequest()
> {
> ResponseResource = new RestApiErrorReply()
> {
> MainDescription = e.Message,
> ExceptionDetail = e.ToString()
> }
> };
> }
> }
> }
>
> What bothers me now is that your code assumes that only
> session.CreateTaskFromOperation could throw an
> InvalidOperationException,
> while in a few months from now it could be possible that other lines
> are throwing InvalidOperationException as well ...
> I would rather see the try catch wrapped on
> session.CreateTaskFromOperation.
> All other exceptions would be logged and a runtime error response
> would be returned.
>
> I say 'recover' since you do not only catch the exception but you also
> handle it, that is, you do not rethrow the exception, effectively you
> have swallowed it.
>
> // Ryan
>
> On Tue, Apr 17, 2012 at 7:50 PM, aa wrote:
> > This is one example of session usage:
> >
> >
> ------------------------------------------------------------------------------------------------------------------------------------------------------
> >
> >
> > [HttpOperation(HttpMethod.POST, ForUriName = "Execute")]
> >
> > public OperationResult Execute(String operationId)
> >
> > {
> >
> > _logger.Info(String.Format
> >
> > ("Operation Manager: Adding a new task to the database
> for
> > Operation with Id ({0})...",
> >
> > operationId));
> >
> >
> > var session = _documentStore.OpenSession();
> >
> > try
> >
> > {
> >
> > Operation operation
> = session.Get<Operation>(operationId);
> >
> > Task task = session.CreateTaskFromOperation();
> >
> >
> > session.Store(task);
> >
> >
> > session.SaveChanges();
> >
> >
> > //Initiate Saga to control the task execution lifetime
> >
> > Bus.SendLocal(new BeginTask() { TaskId = task.Id });
> >
> >
> >
> > TaskDto taskDto = Mapper.Map<Task, TaskDto>(task);
> >
> >
> > return new OperationResult.OK(taskDto);
> >
> >
> > }
> >
> > catch (InvalidOperationException invalidOperationException)
> >
> > {
> >
> > //Tried to create a task from an operation marked as
> > inactive
> >
> >
> >
> _logger.Error(invalidOperationException.Message,invalidOperationException);
> >
> > return new OperationResult.BadRequest()
> >
> > {
> >
> > ResponseResource =
> >
> > new RestApiErrorReply()
> >
> > {
> >
> > MainDescription =
> > invalidOperationException.Message,
> >
> > ExceptionDetail =
> > invalidOperationException.ToString()
> >
> > }
> >
> > };
> >
> >
> >
> > }
> >
> >
> >
> > finally
> >
> > {
> >
> > session.Dispose();
> >
> > }
> >
> > }
> >
> >
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> >
> >
> > I need to catch DB related errors somewhere, I need to catch them NOT to
> > recover from them , I need to catch them to be able to LOG them and send
> > that proper error reply back. If I dont catch them there will be an
> > unhandled exception and the application will crash.
> >
> > This is not running on IIS, is a Windows service and the DB is Embedded.
> >
> > On Tuesday, April 17, 2012 12:40:52 PM UTC-5, Ryan Heath wrote:
> >>
> >> Could you post an example how you recover from session exceptions
> >> right now in your code?
> >>
> >> // Ryan
> >>
> >> On Tue, Apr 17, 2012 at 7:28 PM, aa wrote:
> >>
> >>
> >> > If I dont catch these exceptions the application crashes. Catching
> >> > (Exception) is way to broad. There must be a middle ground.
> >> >
> >> >
> >> >
> >> >
> >> > On Tuesday, April 17, 2012 12:01:11 PM UTC-5, Ryan Heath wrote:
> >> >>
> >> >> You really are recovering from an exception thrown by the session.
> >> >>
> >> >> I do not believe in recovering from exceptions at a higher level. I
> >> >> think
> >> >> if you really want this you need to wrap your session calls with try
> >> >> catch(exception). Perhaps it's even feasible to put it into an helper
> >> >> function.
> >> >>
> >> >> // Ryan
> >> >>
> >> >> On Tuesday, April 17, 2012, aa wrote:
> >> >>>
> >> >>> Hi
> >> >>>
> >> >>> I dont need to recover from an exception, I just need to be able to
> >> >>> catch
> >> >>> them easily and cleanly.
> >> >>>
> >> >>> If I dont catch the exceptions that the session might throw the
> >> >>> application will crash, I just want to catch them, then log the
> >> >>> exception to
> >> >>> the logger (maybe send back some error message to the UI) and
> dispose
> >> >>> the
> >> >>> session.
> >> >>>
> >> >>> Right now to do this I need to catch around 15 exceptions each time
> I
> >> >>> use
> >> >>> the session, how can I achieve what I need without having to catch
> all
> >> >>> of
> >> >>> these exceptions every time I use the session?
> >> >>>
> >> >>> Regards
> >> >>>
> >> >>> On Tuesday, April 17, 2012 3:07:51 AM UTC-5, Oren Eini wrote:
> >> >>>>
> >> >>>> There is no RavenException.
> >> >>>> There is some internal error handling, but in general, the rule is.
> >> >>>> If
> >> >>>> you got an exception from the RavenDB session, that session is
> toast.
> >> >>>> Its
> >> >>>> state is no longer valid, and the only method that you can call on
> it
> >> >>>> is
> >> >>>> dispose.
> >> >>>>
> >> >>>> In general, you'll see three types of exceptions:
> >> >>>> * Network errors - server unreachable, etc.
> >> >>>> * Concurrency errors - someone modified the doc
> >> >>>> * Just plain errors - you tried to do something not possible.
> >> >>>> (document
> >> >>>> key too long, etc).
> >> >>>>
> >> >>>> None of them are really things that you can recover from.
> >> >>>>
> >> >>>> On Mon, Apr 16, 2012 at 11:38 PM,
> >> >>>>>
> >> >>>>> Hello
> >> >>>>>
> >> >>>>> What would be the appropiate way to handle Exceptions or temporary
> >> >>>>> problems with Raven during a UnitOfWork/Session Request using the
> >> >>>>> Client
> >> >>>>> API?
> >> >>>>>
> >> >>>>> In other words what exception we would need to catch in order to
> >> >>>>> handle
> >> >>>>> all problems that might arise while communicating with Raven, is
> >> >>>>> there
> >> >>>>> something akin to SqlException on SqlServer?
> >> >>>>>
> >> >>>>> I have found approximately 15 types of different exceptions that
> >> >>>>> Raven
> >> >>>>> throws, it would be really cumbersome to catch all of these for
> >> >>>>> every
> >> >>>>> session/unitofwork in our application.
> >> >>>>>
> >> >>>>> What would be the best approach in this case?
> >> >>>>>
> >> >>>>> Regards
> >> >>>>> Albert
> >> >>>>
> >> >>>>
> >> >
>
>
------=_Part_154_4908051.1334687351316
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
This would have been much easier with one ExceptionType that encapsulates a=
ll Raven related exceptions.<div><br></div><div>In any event handling (Exce=
ption) only is not ideal, there might be other exceptions that the applicat=
ion might throw that I DO NOT want to catch. There might be exception=
s that might be thrown by ASP.NET itself that are really unexpected and are=
supposed to make the app crash, if I handle everything then there might be=
exceptions that get handled and logged but the application stays running, =
running in an inconsistent state.<br><br>I would have to surround=
only session calls with a try to solve this, this means I will need many t=
ry/catch blocks in each of my controller actions.</div><div><br></div><div>=
Its much easier/cleaner to catch one exception type that you know it comes =
from raven.<br><br>On Tuesday, April 17, 2012 1:14:17 PM UTC-5, Ryan Heath =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">How does it differ from =
this?<p>public OperationResult Execute(String operationId)<br>{<br> _=
logger.Info(String.Format("<wbr>Operation Manager: Adding a new task to<br>=
the database for Operation with Id ({0})...", operationId));<br> usin=
g(var session =3D _documentStore.OpenSession())<br> {<br>  =
; try<br> {<br> Operation operation =3D se=
ssion.Get<Operation>(<wbr>operationId);<br> Task =
task =3D session.<wbr>CreateTaskFromOperation();<br> se=
ssion.Store(task);<br> session.SaveChanges();<br> =
Bus.SendLocal(new BeginTask() { TaskId =3D task.Id });<br>&n=
bsp; TaskDto taskDto =3D Mapper.Map<Task, TaskDto>(task=
);<br> return new OperationResult.OK(taskDto);<br> =
; }<br> catch (Exception e)<br> {<br> =
; _logger.Error(e.Message,e);<br> if !(e =
is InvalidOperationException) ? return new<br>OperationResult.<wbr>Internal=
ServerError() :<br> return new OperationResult.BadReque=
st()<br> {<br> =
ResponseResource =3D new RestApiErrorReply()<br>  =
; {<br> MainDescription =3D=
e.Message,<br> ExceptionDetail =
=3D e.ToString()<br> }<br> &=
nbsp; };<br> }<br> }<br>}</p><p>What bothers me n=
ow is that your code assumes that only<br>session.<wbr>CreateTaskFromOperat=
ion could throw an<br>InvalidOperationException,<br>while in a few months f=
rom now it could be possible that other lines<br>are throwing InvalidOperat=
ionException as well ...<br>I would rather see the try catch wrapped on ses=
sion.<wbr>CreateTaskFromOperation.<br>All other exceptions would be logged =
and a runtime error response<br>would be returned.</p><p>I say 'recover' si=
nce you do not only catch the exception but you also<br>handle it, that is,=
you do not rethrow the exception, effectively you<br>have swallowed it.</p=
><p>// Ryan</p><p>On Tue, Apr 17, 2012 at 7:50 PM, aa wrote:<br>> This i=
s one example of session usage:<br>><br>> ---------------------------=
---<wbr>------------------------------<wbr>------------------------------<w=
br>------------------------------<wbr>------------------------------<br>>=
;<br>><br>> [HttpOperation(HttpMethod.<wbr>POST, ForUriName =3D=
"Execute")]<br>><br>> public OperationRe=
sult Execute(String operationId)<br>><br>>  =
; {<br>><br>> _logger.Info(=
String.Format<br>><br>> &nb=
sp; ("Operation Manager: Adding a new task to the database for<br>&g=
t; Operation with Id ({0})...",<br>><br>> =
operationId));<br>><br>><br>> =
var session =3D _documentStore=
.<wbr>OpenSession();<br>><br>> &nb=
sp; try<br>><br>> {<br>>=
<br>> Operation =
operation =3D session.Get<Operation>(<wbr>operationId);<br>><=
br>> Task task =
=3D session.<wbr>CreateTaskFromOperation();<br>><br>><br>> &n=
bsp; session.Store(ta=
sk);<br>><br>><br>> &nbs=
p; session.SaveChanges();<br>><br>><br>> =
//Initiate Saga to control the t=
ask execution lifetime<br>><br>> &=
nbsp; Bus.SendLocal(new BeginTask() { TaskId =3D task.Id });<=
br>><br>><br>><br>> &=
nbsp; TaskDto taskDto =3D Mapper.Map<Task, TaskDto>(task);<br>=
><br>><br>>  =
; return new OperationResult.OK(taskDto);<br>><br>><br>> &n=
bsp; }<br>><br>> &nb=
sp; catch (InvalidOperationException invalidOperationExceptio=
n)<br>><br>> {<br>><br>&=
gt; //Tried to crea=
te a task from an operation marked as<br>> inactive<br>><br>><br>&=
gt; _logger.Error(<wbr>invalidOperationException.<wbr>Message,<wbr>invalidO=
perationException);<br>><br>> &nbs=
p; return new OperationResult.BadRequest()<br>><br>> &n=
bsp; &=
nbsp; {<br>><br>> &nb=
sp; R=
esponseResource =3D<br>><br>>  =
; &nb=
sp; new RestApiErrorReply()<br>><br>> &nbs=
p; &n=
bsp; {<br>><br>> &nbs=
p; &n=
bsp; MainDescriptio=
n =3D<br>> invalidOperationException.<wbr>Message,<br>><br>>  =
; &nbs=
p; Ex=
ceptionDetail =3D<br>> invalidOperationException.<wbr>ToString()<br>>=
<br>> &nbs=
p; }<=
br>><br>> &nbs=
p; };<br>><br>><br>><br>> &n=
bsp; }<br>><br>><br>><br>> &=
nbsp; finally<br>><br>> &nb=
sp; {<br>><br>> &nbs=
p; session.Dispose();<br>><br>> &n=
bsp; }<br>><br>> &nb=
sp; }<br>><br>> ------------------------------<wbr>------------------=
------------<wbr>------------------------------<wbr>-----------------------=
-------<wbr>------------------------------<wbr>----------------------------=
--<wbr>------------------------------<wbr>---------------<br>><br>><b=
r>> I need to catch DB related errors somewhere, I need to catch them NO=
T to<br>> recover from them , I need to catch them to be able to LOG the=
m and send<br>> that proper error reply back. If I dont catch them=
there will be an<br>> unhandled exception and the application will cras=
h.<br>><br>> This is not running on IIS, is a Windows service and the=
DB is Embedded.<br>><br>> On Tuesday, April 17, 2012 12:40:52 PM UTC=
-5, Ryan Heath wrote:<br>>><br>>> Could you post an example how=
you recover from session exceptions<br>>> right now in your code?<br=
>>><br>>> // Ryan<br>>><br>>> On Tue, Apr 17, 2012 =
at 7:28 PM, aa wrote:<br>>><br>>><br>>> > If I d=
ont catch these exceptions the application crashes. Catching<br>>&=
gt; > (Exception) is way to broad. There must be a middle ground.<=
br>>> ><br>>> ><br>>> ><br>>> ><br>>=
> > On Tuesday, April 17, 2012 12:01:11 PM UTC-5, Ryan Heath wrote:<b=
r>>> >><br>>> >> You really are recovering from an =
exception thrown by the session.<br>>> >><br>>> >> =
I do not believe in recovering from exceptions at a higher level. I<br>>=
> >> think<br>>> >> if you really want this you need t=
o wrap your session calls with try<br>>> >> catch(exception). P=
erhaps it's even feasible to put it into an helper<br>>> >> fun=
ction.<br>>> >><br>>> >> // Ryan<br>>> >&g=
t;<br>>> >> On Tuesday, April 17, 2012, aa wrote:<br>>> &=
gt;>><br>>> >>> Hi<br>>> >>><br>>>=
; >>> I dont need to recover from an exception, I just need to be =
able to<br>>> >>> catch<br>>> >>> them easily=
and cleanly.<br>>> >>><br>>> >>> If I dont c=
atch the exceptions that the session might throw the<br>>> >>&g=
t; application will crash, I just want to catch them, then log the<br>>&=
gt; >>> exception to<br>>> >>> the logger (maybe se=
nd back some error message to the UI) and dispose<br>>> >>> =
the<br>>> >>> session.<br>>> >>><br>>> =
>>> Right now to do this I need to catch around 15 exceptions each=
time I<br>>> >>> use<br>>> >>> the session, =
how can I achieve what I need without having to catch all<br>>> >&=
gt;> of<br>>> >>> these exceptions every time I use the s=
ession?<br>>> >>><br>>> >>> Regards<br>>&g=
t; >>><br>>> >>> On Tuesday, April 17, 2012 3:07:51=
AM UTC-5, Oren Eini wrote:<br>>> >>>><br>>> >&g=
t;>> There is no RavenException.<br>>> >>>> There i=
s some internal error handling, but in general, the rule is.<br>>> &g=
t;>>> If<br>>> >>>> you got an exception from th=
e RavenDB session, that session is toast.<br>>> >>>> Its<=
br>>> >>>> state is no longer valid, and the only method =
that you can call on it<br>>> >>>> is<br>>> >>=
;>> dispose.<br>>> >>>><br>>> >>>>=
; In general, you'll see three types of exceptions:<br>>> >>>=
;> * Network errors - server unreachable, etc.<br>>> >>>&=
gt; * Concurrency errors - someone modified the doc<br>>> >>>=
;> * Just plain errors - you tried to do something not possible.<br>>=
> >>>> (document<br>>> >>>> key too long, =
etc).<br>>> >>>><br>>> >>>> None of the=
m are really things that you can recover from.<br>>> >>>>=
<br>>> >>>> On Mon, Apr 16, 2012 at 11:38 PM,<br>>>=
>>>>><br>>> >>>>> Hello<br>>> &g=
t;>>>><br>>> >>>>> What would be the appro=
piate way to handle Exceptions or temporary<br>>> >>>>>=
; problems with Raven during a UnitOfWork/Session Request using the<br>>=
> >>>>> Client<br>>> >>>>> API?<br>&=
gt;> >>>>><br>>> >>>>> In other word=
s what exception we would need to catch in order to<br>>> >>>=
;>> handle<br>>> >>>>> all problems that might a=
rise while communicating with Raven, is<br>>> >>>>> th=
ere<br>>> >>>>> something akin to SqlException on SqlS=
erver?<br>>> >>>>><br>>> >>>>> I =
have found approximately 15 types of different exceptions that<br>>> =
>>>>> Raven<br>>> >>>>> throws, it woul=
d be really cumbersome to catch all of these for<br>>> >=
>>>> every<br>>> >>>>> session/unitofwork =
in our application.<br>>> >>>>><br>>> >>&g=
t;>> What would be the best approach in this case?<br>>> >&g=
t;>>><br>>> >>>>> Regards<br>>> >>=
;>>> Albert<br>>> >>>><br>>> >>>&=
gt;<br>>> ><br></p><p></p><p></p><p></p><p></p></blockquote></div>
------=_Part_154_4908051.1334687351316--
------=_Part_153_28365935.1334687351315--